1. 定义与触发条件
回流(Reflow/重排)
-
定义:当浏览器需要重新计算元素的位置、尺寸或布局时触发,导致渲染树(Render Tree)的重新构建。
-
触发条件:
- 添加或删除可见的 DOM 元素
- 元素尺寸变化(如宽度、高度、边距、边框等)
- 元素位置变化(如
top、left、right、bottom) - 页面初始化或窗口大小改变
- 访问某些样式属性(如
offsetTop、scrollHeight等会触发强制同步布局)
-
影响范围:通常会影响整个渲染树或部分子树,性能开销较大。
重绘(Repaint)
-
定义:当元素的外观(如颜色、背景色、阴影等)改变,但布局未发生变化时触发。
-
触发条件:
- 修改元素的
color、background-color、visibility等视觉属性 - 元素的
opacity变化(某些浏览器可能触发合成层升级)
- 修改元素的
-
影响范围:仅影响元素自身及其子元素(如果被覆盖),性能开销较小。
2. 执行顺序与依赖关系
- 回流必然触发重绘:
如果布局发生变化(回流),浏览器必须重新绘制受影响的元素(重绘)。 - 重绘不触发回流:
仅修改视觉样式时,浏览器只需重绘,无需重新计算布局。
3. 性能影响与优化
回流(Reflow)的性能开销
-
高开销操作:回流需要重新计算布局树,可能涉及复杂的计算(如浮动、绝对定位、Flexbox/Grid 布局)。
-
优化建议:
- 避免频繁修改样式(如通过
classList批量操作)。 - 使用
transform和opacity替代top/left(触发硬件加速,减少回流)。 - 避免在循环中直接操作 DOM 或读取布局属性(如
offsetWidth)。 - 使用
requestAnimationFrame合并动画帧。
- 避免频繁修改样式(如通过
重绘(Repaint)的性能开销
-
低开销操作:重绘仅涉及像素填充,性能开销较小。
-
优化建议:
- 减少不必要的视觉样式修改(如避免频繁切换背景色)。
- 使用
will-change提示浏览器优化特定元素的绘制(但需谨慎使用,避免滥用)。
4. 关键区别总结
| 维度 | 回流(Reflow) | 重绘(Repaint) |
|---|---|---|
| 触发条件 | 布局或几何属性变化(如尺寸、位置) | 视觉样式变化(如颜色、背景) |
| 性能开销 | 高(重新计算布局树) | 低(仅重绘像素) |
| 依赖关系 | 必然触发重绘 | 不触发回流 |
| 优化方向 | 减少 DOM 操作、使用硬件加速 | 减少样式修改频率、使用 will-change 提示 |
5. 实际开发中的注意事项
- 避免在渲染前频繁查询布局属性:
例如,避免在循环中同时读写offsetWidth和修改样式,这会导致多次回流。 - 使用 CSS 动画替代 JavaScript 动画:
CSS 的transform和opacity动画通常由 GPU 加速,性能更好。 - 使用开发者工具分析性能:
Chrome DevTools 的 Performance 面板可以记录回流和重绘的耗时。
总结
- 回流是性能杀手:应尽量减少回流操作,尤其是避免在关键渲染路径中触发。
- 重绘相对轻量:但仍需避免不必要的重绘(如频繁切换类名)。
- 优化核心原则:批量操作 DOM、减少布局查询、利用硬件加速。