Checking Width And Setting Width Inside Foreach Loop Performance
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:
forEach
with immediately gettingoffsetWidth
and settingwidth
forEach
with storingoffsetWidth
and the corresponding element first and then setting width it in a secondforEach
map
with storingoffsetWidth
and then settingwidth
on the elements in aforEach
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"