0%

浏览器回流(Reflow)与重绘(Repaint)及其思考

我们知道浏览器在解析文档时,会经历以下步骤:

  1. HTML解析为DOM,将CSS解析为CSSOMDOMCSSOM合并生成Render Tree
  2. 然后根据Render Tree将节点绘制在页面上

所谓回流是当元素尺寸、结构或者某些属性发生改变时,浏览器重新部分或者全部渲染文档的过程。
所谓重绘是指元素样式发生改变但并未改变其在文档流中的位置。

回流(Reflow)

我们理解了回流之后再看看哪些操作会导致浏览器回流:

  1. 浏览器窗口大小发生改变
  2. 元素尺寸或者位置发生变化
  3. 元素内容变化
  4. 元素字体变化
  5. 添加或删除DOM
  6. 激活CSS伪类
  7. 查询某些属性或调用某些方法:
    • clientWidth、clientHeight、clientTop、clientLeft
    • offsetWidth、offsetHeight、offsetTop、offsetLeft
    • scrollWidth、scrollHeight、scrollTop、scrollLeft
    • scrollIntoView()、scrollIntoViewIfNeeded()
    • getComputedStyle()
    • getBoundingClientRect()
    • scrollTo()

重绘(Repaint)

当页面中元素的样式改变并不影响其在文档流中得到位置时,浏览器紧紧将新样式赋给它并重新绘制,这就是重绘。例如color、background-color、visibility

思考

既然这样那么我们如何避免重绘与回流呢?

  • 避免使用table布局
  • 将动画效果应用到position属性为absolutefixed的元素上,脱离文档流的元素不会引起回流
  • 可以使用tranform属性来设置动画
  • 避免频繁操作样式,最好使用class来更改样式
  • 避免频繁操作DOM,创建一个documentFragment,在它上面进行DOM操作
  • 可以先将元素设为display:none,操作后再把它显示出来。因为在displaynone的元素上操作不会引起重绘与回流