learning-note icon indicating copy to clipboard operation
learning-note copied to clipboard

如何减少重排(reflow)和重绘(repaint)

Open jackPanyj opened this issue 8 years ago • 0 comments

简单介绍重排和重绘

DOM 的变化影响元素的几何属性的时候,浏览器需要是渲染树中受影响的部分失效

并重新构造渲染树这个过程称为 重排, 完成重排后,浏览器会重新绘制受影响的部分到

屏幕上,这个过程称为 重绘

从上面的解释中我们可以得出:

  1. 重排一定会导致重绘
  2. 重绘不一定会导致重排,当改变的属性不影响几何变化时,比如 background-color属性就不会引发重排,只会发生重绘

重排和重绘都会引发性能问题, 我们能做的就是尽可能减少 重排重绘 的次数,尤其是重排的次数

大多数浏览器对重排做了优化,但是下面这几个属性的获取会使得浏览器立即发生重排

  • offsetTop, offsetLeft, offsetWidth, offsetHeight
  • scrollTop, scrollLeft, scrollWidth, scrollTopHeight
  • clientTop, clientLeft, clientWidth, clientHeight
  • getComputedStyle()

所以尽量避免使用以上属性

最小化重排和重绘

  1. 属性的读和写放在一块,不要读了写,写了读,比如:

    var computed = document.defaultView.getComputedStyle(document.body),
        bodyStyle = document.body.style,
        tmp;
    bodyStyle.backgroundColor = 'red'
    tmp = computed.backgroundColor
    bodyStyle.backgroundColor = 'blue'
    tmp = computed.backgroundColor
    bodyStyle.backgroundColor = 'teal'
    tmp = computed.backgroundColor
    

    这样写的话,浏览器至少在此期间发生了三次重绘。应该怎么写相信大家很清楚了。

2.修改样式多的时候尽量使用 class 或者 cssText, 如:

    var el = document.getElementById('mydiv')
    el.style.borderLeft = '1px'
    el.style.borderRight = '2px'
    el.style.padding = '5px'

最糟糕的情况上面会发生三次重排

修改后为:

    var el = document.getElementById('mydiv')
    el.style.cssText += 'borderLeft: 1px; borderRight: 2px; padding: 5px'

这样的话就只会发生一次重排

当然也可以用class来实现, 这样会使你的代码可读性更高

jackPanyj avatar May 12 '16 10:05 jackPanyj