Skip to content Skip to sidebar Skip to footer

Checking Width And Setting Width Inside Foreach Loop Performance

I have two pieces of code below Snippet#1 const doubleWidth = (element) => { const width = element.offsetWidth; element.style.width = `${width * 2}px`; }; button.addEventLis

Solution 1:

in Snippet 1 each time you are executing 2 commands:

const width = element.offsetWidth;
element.style.width = `${width * 2}px`;

while in Snippet 2 each time you are executing only 1 command:

element.style.width = `${widths[index] * 2}px`;

Therefore I think it's natural to have more than double the time for the execution. depending on how much time it take to execute the following command:

const width = element.offsetWidth;

For a fair comparison between the 2 snippets I would suggest removing the above command from the loop and check how long it would take to execute snippet 1 in that case.

I hope that helps.

Solution 2:

I'm not sure about the reason, but apparently if you store offsetWidth first, it doesn't matter performance-wise whether you use forEach or map: here's a pen to illustrate this behavior.

You can see that I timed three combinations:

  1. forEach with immediately getting offsetWidth and setting width
  2. forEach with storing offsetWidth and the corresponding element first and then setting width it in a second forEach
  3. map with storing offsetWidth and then setting width on the elements in a forEach loop

Option 2. an 3. were basically the same performance wise. Judging from that, I would say that the combination of getting offsetWidth and setting width is a performance bottleneck. Can't really tell you much more than that, sorry!


window.onload = () => {
    const boxes = Array.from(document.querySelectorAll('.box'));

    document.getElementById('double-sizes-forEach')
    .addEventListener('click', (event) => {
        console.time('Double Sizes ForEach');

        boxes.forEach((element, index) => {
        const width = element.offsetWidth;
        element.style.width = `${width * 2}px`;
        });

        console.timeEnd('Double Sizes ForEach');
    });

    document.getElementById('double-sizes-forEach-2')
    .addEventListener('click', (event) => {
        console.time('Double Sizes ForEach 2');

        let a = [];
        boxes.forEach((element, index) => {
        a.push([element, element.offsetWidth]);
        });
        a.forEach(([e, w]) => {
        e.style.width = `${w * 2}px`; 
        });

        console.timeEnd('Double Sizes ForEach 2');
    });

    document.getElementById('double-sizes-map')
    .addEventListener('click', (event) => {
        console.time('Double Sizes Map');

        var widths = boxes.map(item => item.offsetWidth);
        boxes.forEach((element, index) => {
            element.style.width = `${widths[index] * 2}px`;
        });

        console.timeEnd('Double Sizes Map');
    });
};

OUTPUT:

Double Sizes ForEach: 12.341064453125ms
Double Sizes ForEach2: 0.539794921875ms
Double Sizes Map: 0.590087890625ms

NOTES:

The second article argues that you should always separate changing style (e.g. setting width) and taking measurements (e.g. getting offsetWidth) to avoid layout thrashing. Seems that's the problem in your code as well.

Post a Comment for "Checking Width And Setting Width Inside Foreach Loop Performance"