我下面有两段代码
代码段1
const doubleWidth = (element) => {
const width = element.offsetWidth;
element.style.width = `${width * 2}px`;
};
button.addEventListener('click', (event) => {
boxes.forEach(doubleWidth);
});
代码段2
button.addEventListener('click', (event) => {
var widths = boxes.map(item => item.offsetWidth);
boxes.forEach((element, index) => {
element.style.width = `${widths[index] * 2}px`;
});
});
与片段2(只有18.4ms)相比,片段1有48ms的时间。为什么会这样?
毕竟,我仍然分别进行两项计算和设置操作(哪些是强行回流)。
这是完整的代码-https://codepen.io/kushalmahajan/pen/mjXVqp?editors=0010
更新-所以,让我解释一下
在代码片段1中,我每次都会看到诸如计算,重置,计算,重置...之类的模式
在代码段2中。事实并非如此。
请根据渲染管道为您提供答案
答案 0 :(得分:0)
每次执行2条命令:
const width = element.offsetWidth;
element.style.width = `${width * 2}px`;
在摘录2中 每次只执行1条命令:
element.style.width = `${widths[index] * 2}px`;
因此,我认为将执行时间增加一倍以上是很自然的。取决于执行以下命令所需的时间:
const width = element.offsetWidth;
为了在2个代码段之间进行合理的比较,我建议从循环中删除以上命令,并检查在这种情况下执行代码段1需要多长时间。
我希望有帮助。
答案 1 :(得分:0)
我不确定原因,但是很明显,如果您先存储offsetWidth
,则使用forEach
或map
的性能无关紧要:{{3 }}。
您可以看到我对三种组合进行了计时:
forEach
,并立即获取offsetWidth
并设置width
forEach
,首先存储offsetWidth
和相应的元素,然后在第二个forEach
中设置宽度map
,先存储offsetWidth
,然后在width
循环中的元素上设置forEach
选项 2。和 3。在性能上基本相同。从这一点来看,我想说获得offsetWidth
和设置width
的组合是一个性能瓶颈。真的不能告诉你更多,对不起!
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');
});
};
输出:
Double Sizes ForEach: 12.341064453125ms
Double Sizes ForEach 2: 0.539794921875ms
Double Sizes Map: 0.590087890625ms
注释:
第二篇文章认为,您应该始终将更改样式(例如,设置width
)和进行测量(例如,获取offsetWidth
)分开,以免发生布局问题。似乎也是代码中的问题。