Skip to content

重绘与重排

约 1075 字大约 4 分钟

重绘&重排浏览器前端开发

2025-06-24

什么是重排(Reflow)?

重排(Reflow)

重排(Reflow) 是指当 DOM 的几何信息发生变化 时,浏览器需要重新计算元素的布局位置及大小,并将其放置到正确的位置。

触发重排的场景

  • 添加、删除或更新 DOM 节点。
  • 改变元素的几何属性(如 widthheightpaddingmarginborder 等)。
  • 元素的显示状态从 display: none 切换为可见。
  • 浏览器窗口大小变化。
  • 动画导致元素的几何属性变化(如移动、缩放等)。
  • 修改字体大小或内容改变导致文本流重新计算。

💡 注意重排是性能开销最大的操作,因为它会导致整个页面或部分页面重新计算布局

什么是重绘(Repaint)?

重排(Reflow)

重绘(Repaint) 是指当 元素的外观发生变化(如颜色、背景、阴影等),但不影响其几何属性时,浏览器会重新绘制这些元素的外观。

触发重绘的场景

  • 改变元素的颜色(如 colorbackground-color)。
  • 改变元素的边框样式(如 border-color)。
  • 设置元素的透明度(如 opacity)。
  • 元素的显示状态从 visibility: hidden 切换为可见。

⚠️ 区别:重绘不影响布局,因此它的性能开销通常小于重排

重排和重绘的关系

  • 重排必然会触发重绘:因为页面布局的改变会影响元素的外观。
  • 重绘不一定会触发重排:如果仅仅是外观变化(如颜色),不会影响布局。

🚨 总结:重排的性能消耗更高,因此在开发中应尽量避免频繁触发重排操作。

如何优化避免重排与重绘?

1. 减少 DOM 操作

  • 合并多次 DOM 更新:集中修改 DOM,而不是逐条操作。
  • 离线更新 DOM:使用 DocumentFragment 或克隆节点在内存中操作,完成后一次性更新到 DOM 中。

2. 避免循环中操作 DOM

将 DOM 属性值提取到变量中,在循环外部完成修改。

3. 使用合适的显示属性

  • 使用 visibility: hidden 代替 display: none,因为前者只触发重绘,而后者会触发重排。
  • 为频繁变化的元素设置 position: absolutefixed,可以减少对其他元素的影响。

4. 动画优化

  • 使用 transformopacity 来实现动画,因为它们不会触发回流或重绘。
  • 启用 GPU 加速,通过 translate3dwill-change 提升性能。

5. 避免使用 Table 布局

Table 的布局依赖于其子元素的几何信息,任何改动都会导致整个表格重新计算布局。

6. 减少样式计算和重排

  • 避免频繁读取会触发回流的属性(如 offsetWidthoffsetHeight 等),可以将其缓存到变量中。
  • 使用 class 切换样式而不是逐条修改样式属性。

提升合成层的性能优化

合成层是浏览器单独为某些元素创建的图层,可以有效减少重排和重绘的开销。

如何提升元素为合成层?

  • 使用 will-change 属性。
  • 使用 3D 变换(如 translate3d)。

合成层的优点

  1. GPU 优化:合成层的位图会交由 GPU 合成,比 CPU 处理更快。
  2. 局部重绘:合成层只会重绘自身,不会影响其他层。
  3. 避免回流transformopacity 等效果不会触发重排和重绘。

总结

在浏览器渲染过程中,重排和重绘是不可避免的,但可以通过优化代码减少它们的频繁触发。以下是关键点总结:

  1. 重排比重绘性能开销更大,应尽量减少重排操作
  2. 使用合适的优化策略:如集中修改样式、缓存属性值、使用合成层等。
  3. 利用 GPU 加速和 CSS 动画,提升页面的渲染性能。

🚀 性能优化建议:减少 DOM 操作与回流重排,使用现代化的开发工具和框架(如 React 和 Vue)可以帮助开发者更高效地优化页面性能和用户体验。