阻止浏览器在javascript中呈现CSS更改?

时间:2013-12-02 21:17:38

标签: javascript css css3 requestanimationframe

我有以下代码块需要尽快完成:

//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可能是做我正在寻找的事情的关键,但也许我不在基地。

1 个答案:

答案 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"