什么是 repaint?
在浏览器渲染网页的过程中,repaint(重绘)是指当元素的外观发生变化(如颜色、背景等)但不影响其几何位置时,浏览器重新绘制该元素的过程。
然而,在触发 repaint 之前,浏览器已经完成了多个关键阶段。理解这些阶段有助于我们写出更高效的前端代码。
repaint 前的关键阶段
1. 解析 HTML 构建 DOM 树
浏览器从服务器接收到 HTML 文档后,会逐行解析并构建 DOM(Document Object Model)树。每个 HTML 元素都成为 DOM 树中的一个节点。
2. 解析 CSS 构建 CSSOM 树
同时,浏览器会加载并解析所有 CSS 规则,生成 CSSOM(CSS Object Model)。CSSOM 描述了每个元素应如何被样式化。
3. 合并 DOM 与 CSSOM 形成 Render Tree
浏览器将 DOM 和 CSSOM 合并为一棵 Render Tree(渲染树),其中只包含需要显示的可见节点(例如,display: none 的元素不会被包含)。
4. Layout(布局 / 回流)
在 Layout 阶段(也称为 Reflow),浏览器计算每个 Render Tree 节点在视口中的确切位置和尺寸。这个过程依赖于盒模型、浮动、定位等 CSS 属性。
注意:Layout 是一个代价较高的操作,频繁触发会导致性能问题。
5. Paint Setup(绘制准备)
在正式绘制前,浏览器会确定哪些元素需要绘制、分层(layers)、以及绘制顺序。这一阶段为后续的 repaint 做准备。
何时会触发 repaint?
当元素的视觉样式(如 color、background-color、visibility 等)改变,但不改变其几何尺寸或位置时,浏览器会跳过 Layout 阶段,直接进入 repaint。
示例:
element.style.backgroundColor = 'blue'; // 触发 repaint,但不触发 reflow
性能建议
- 避免频繁修改样式,可使用 class 批量切换。
- 使用
transform和opacity实现动画,它们通常只触发合成(composite),不触发 layout 或 paint。 - 利用 DevTools 的 Performance 面板分析渲染瓶颈。