我有以下代码块需要尽快完成:
//someSpans is an array of spans, with each span containing two child spans inside of it
$.each( someSpans, function (i, span) {
//Get the span widths, then add them to the style to make them permanent
var aSpan = span.children[0];
var bSpan = span.children[1];
span.style.width = (aSpan.offsetWidth + bSpan.offsetWidth) + 'px';
aSpan.style.width = aSpan.offsetWidth + 'px';
bSpan.style.width = bSpan.offsetWidth + 'px';
});
如果someSpans是一个包含1000个对象的数组,则上面显示的这个循环将导致3000次浏览器重绘,即使屏幕上没有任何内容实际发生变化,因为样式中新的“width”属性与现有的“auto”宽度匹配。有没有办法阻止浏览器重新绘制CSS直到循环结束?我觉得这会大大减少循环完成所需的时间。
我觉得requestAnimationFrame可能是做我正在寻找的事情的关键,但也许我不在基地。
答案 0 :(得分:2)
虽然为什么的评论非常重要,但这里的答案会更好。
这里的部分问题是来自样式的交替读/写。也就是说,设置span.style.width
现在已经aSpan.offsetWidth
"脏"并且必须呈现CSS。但是,请考虑一下:
var aWidth = aSpan.offsetWidth;
var bWidth = bSpan.offsetWidth;
span.style.width = (aWidth + bWidth) + 'px';
aSpan.style.width = aWidth + 'px';
bSpan.style.width = bWidth + 'px';
渲染现在每个循环减少一次。更具体地说,它正在阅读导致渲染的 next 迭代中的offsetWidth
。
练习虽然它可以使代码更加迟钝,有时也会不必要,但我有时会编写这样的代码来循环两次。第一次将操作收集到一个数组中,第二个循环能够组合所有"设置"没有访问任何布局值的操作。
MSDN有一些很棒的documents on JavaScript performance,其中最适用的是"Managing layout efficiently"