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

时间:2014-09-26 15:28:12

标签: javascript performance reflow

使用具有潜在大型JS库,视图模板,验证,ajax,动画等的非常动态的UI(想想单页应用程序)时...有哪些策略可以帮助最小化或减少浏览器花费的时间在回流?

例如,我们知道有很多方法可以实现DIV大小更改,但有哪些技术应该避免(从回流的角度来看)以及浏览器之间的结果有何不同?

以下是具体示例:

给出一个简单的例子,说明在调整窗口大小时控制DIV大小的3种不同方法,应该使用哪些方法来最小化回流?

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)
    });
});

1 个答案:

答案 0 :(得分:6)

最好尽量避免更改DOM元素。有时你可以通过坚持使用CSS属性来防止重排,或者,如果需要,可以使用CSS'transform来使元素本身不受影响,而是改变了视觉状态。 Paul Lewis和Paul Irish在this article中详细说明了为什么会出现这种情况。

这种方法并不适用于所有情况,因为有时需要更改实际的DOM元素,但对于许多动画等,transform会带来最佳性能。


如果您的操作确实需要重排,您可以通过以下方式将其影响降至最低:

  • 保持DOM深度小
  • 保持CSS选择器简单(并将复杂的选择器保存到JavaScript中的变量)
  • 避免内嵌样式
  • 避免布局表格
  • 尽可能避免使用JavaScript

Nicole Sullivan在这个主题上发布了pretty good article,其中详细介绍了浏览器的重排和重绘。

如果您实际上是在更改DOM而不是DOM属性,那么最好以较大的块(而不是较小的块like this Stack Overflow post表示)进行更改。


在您提供的示例中,第二种方法是最好的,因为它使用CSS属性而不需要JavaScript。浏览器非常擅长渲染元素,其尺寸和位置仅由CSS决定。但是,并不总是可以使用纯CSS来获取我们需要的元素。

最糟糕的方法是到目前为止的第三种方法,因为jQuery的动画开始时非常慢,但是在调整大小时激活使得动画堆叠在彼此之上,所以如果你根本调整大小,它就会落后了。您可以通过使用布尔值设置超时来检查它是否已被触发,或者更优选地,不使用jQuery的动画来完成此操作,而是使用jQuery的.css(),因为调整大小函数会触发通常,无论如何它都会看起来很动画。