【问题标题】:What is the most efficient way to modify DOM elements and limit reflow?修改 DOM 元素和限制重排的最有效方法是什么?
【发布时间】:2014-11-29 01:06:12
【问题描述】:

当使用具有潜在大型 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)
    });
});

【问题讨论】:

  • 请注意,您在第一种方法中两次覆盖了 style 属性。这可能不是你想做的。

标签: javascript performance reflow


【解决方案1】:

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

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


如果您的操作确实需要回流,您可以通过以下方式最小化它的影响:

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

Nicole Sullivan 就该主题发布了 pretty good article,详细介绍了浏览器重排和重绘。

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


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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-03
    • 1970-01-01
    • 1970-01-01
    • 2012-05-22
    相关资源
    最近更新 更多