什么是修改DOM元素和限制重排的最有效方法?

5
当处理非常动态的UI(比如单页应用)时,可能会有大型JS库、视图模板、验证、ajax、动画等等,有哪些策略可以帮助最小化或减少浏览器在回流上花费的时间?
例如,我们知道有许多方法可以实现DIV大小的变化,但是有哪些技术应该避免(从回流的角度来看),在不同的浏览器中结果有何不同?
这里有一个具体的例子:
给出一个简单的例子,有3种不同的方式来控制DIV的大小,当窗口大小改变时,哪种方式应该被使用以最小化回流?

http://jsfiddle.net/xDaevax/v7ex7m6v/

//Method 1: Pure Javascript
function resize(width, height) {
    var target = document.getElementById("method1");
    target.setAttribute("style","width:" + width + "px");
    target.setAttribute("style", "height:" + height + "px");
    console.log("here");
} // end function
window.onresize = function() {
    var height = (window.innerHeight / 4);
    var width = (window.innerWidth / 4);
    console.log(height);
    resize(height, width);
}
//Method #3 Jquery animate
$(function() {
    $(window).on("resize", function(e, data) {
        $("#method3").animate({height: window.innerHeight / 4, width: window.innerWidth / 4}, 600)
    });
});

请注意,在您的第一个方法中,您两次覆盖了_style属性_。这可能不是您想要做的。 - Paul S.
1个回答

6
尽可能避免更改DOM元素是最好的。有时,您可以通过坚持使用CSS属性或必要时使用CSS的“transform”来完全防止回流,以便元素本身不受影响,而是仅更改视觉状态。 Paul Lewis和Paul Irish在这篇文章中详细介绍了为什么会出现这种情况。
这种方法并非在所有情况下都适用,因为有时需要更改实际的DOM元素,但对于许多动画等,transform提供了最佳性能。
如果您的操作确实需要回流,则可以通过以下方式将其最小化:
- 保持DOM深度较小 - 使CSS选择器简单(并将复杂的选择器保存到JavaScript变量中) - 避免内联样式 - 避免使用表格进行布局 - 尽可能避免使用JavaScript
Nicole Sullivan在这篇文章中发表了一篇相当不错的文章,详细介绍了浏览器回流和重绘。
如果您实际上正在更改DOM而不是DOM属性,最好将其分批处理,而不是像此Stack Overflow帖子建议的那样逐个更改。
在您提供的示例中,第二种方法是最好的,因为它使用CSS属性而不需要JavaScript。浏览器非常擅长渲染仅由CSS确定尺寸和位置的元素。但是,不总能通过纯CSS将元素放置在所需位置。
最糟糕的方法无疑是第三种方法,因为jQuery的animate本来就很慢,但是让它在调整大小时运行会使动画叠加在一起,因此如果您调整大小,则会严重滞后。您可以通过设置具有检查其是否已被触发的布尔值的超时来防止这种情况,或者更好的是根本不要使用jQuery的animate来完成此操作,而是使用jQuery的.css(),因为resize函数经常触发,因此它看起来已经是动画了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接