# 回流(Reflow)和重绘(Repaint)

  • 渲染流水线(主线程):生成 DOM 树 -> 计算样式 -> 生成布局树 -> 建图层树 -> 生成绘制列表

# 回流

回流也叫重排

  • 触发条件
    对 DOM 结构的修改引发 DOM 几何尺寸变化的时候,会发生回流
  • 触发回流的时候,如果 DOM 结构改变,则重新渲染 DOM 树,然后将后面的流程(包括主线程之外的任务)全部走一遍,开销非常大

# 重绘

当 DOM 的修改导致了样式的变化,并且没有影响几何属性的时候,会导致重绘

  • 跳过了生成布局树和建图层树的阶段,直接生成绘制列表,然后继续进行分块、生成位图等后面一系列操作

重绘不一定导致回流,但是回流一定发生了重绘

# 合成

  • 更新视图的另外一种方式 —— 合成,直接合成
  • 在合成的情况下,会直接跳过布局和绘制流程,直接进入非主线程处理的部分,即直接交给合成线程处理
  • 优势:
    1. 充分发挥 GPU 的优势,合成线程生成位图的过程中会调用线程池,并在其中使用 GPU 进行加速生成,而 GPU 是擅长处理位图数据的
    2. 没有占用主线程的资源,即使主线程卡住了,效果依然可以流畅的展示

# 实践

  1. 避免频繁的使用 style,而是采用 class 的方式
  2. 使用 createElementFragment 进行批量的 DOM 操作
  3. 对 resize、scroll 等进行防抖节流处理
  4. 在必要的时候把元素提升为单独的图层,使用 will-change: transform;translate3d
    当提升为一个单独的图层,发生变换的时候直接进行合成的步骤
Last Updated: 5/6/2020, 11:48:16 AM