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:
forEachwith immediately gettingoffsetWidthand settingwidthforEachwith storingoffsetWidthand the corresponding element first and then setting width it in a secondforEachmapwith storingoffsetWidthand then settingwidthon the elements in aforEachloop
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"