好的,继续 第 38 题:浏览器渲染流程(Reflow 重排、Repaint 重绘、Composite 合成)
这是前端工程师必须完全掌握的核心知识。
✅ 第 38 题:浏览器渲染流程(Reflow、Repaint、Composite)
我会按你需要的深入版来讲:
- 渲染管线原理(面试官想听的版本)
- 重排与重绘的区别(必考)
- 哪些操作会触发重排(高频陷阱)
- 如何优化渲染性能(你写项目能用)
- 速记卡片
一、浏览器渲染的完整流程(Pipeline)
页面渲染大致分为 7 步:
css
HTML 解析 → DOM
CSS 解析 → CSSOM
↓
生成 Render Tree(渲染树)
↓
布局(Layout / Reflow) ← 计算位置和大小
↓
绘制(Paint / Repaint) ← 画出像素
↓
合成(Composite) ← GPU 合成图层
这是每个浏览器(Chrome / Safari / Firefox)的核心渲染流程。
二、关键的三个阶段(重排、重绘、合成)
面试题几乎都问这三个。
1)Reflow(重排、布局)
改动影响尺寸、位置、结构 → 必须重新计算布局 → 导致 Reflow
会触发重排的典型操作:
- 修改宽高(width/height)
- 修改位置(top/left)
- 修改字体大小(font-size)
- 修改 display、visibility(尤其 display: none)
- 内容变化导致大小变化(如 innerText、appendChild)
- 页面大小变化(resize)
重排是最耗性能的阶段。
👉 一句话记:影响布局 = 重排
2)Repaint(重绘)
如果只是改变外观,不改变大小与布局 → 重绘
典型触发:
- color
- background
- border-color
- box-shadow
注意:border-width 改变会触发重排,但 border-color 不会。
👉 一句话记:影响外观 = 重绘
3)Composite(合成)
如果使用了 独立图层(composite layer) ,浏览器可以跳过 Reflow 和 Repaint。
直接由 GPU 合成。
能触发 Composite 的属性(通常只影响合成层):
- transform(translate/scale/rotate)
- opacity
- will-change
这类操作性能最好,动画最流畅,60fps 没问题。
👉 一句话记:transform + opacity → 最快
三、面试官最爱问:哪些操作会触发 Reflow?(牢记)
✔ 下面这些会触发 Reflow(重排)
- 改变几何属性(width/height/margin/padding/top/left)
- 改变 font-size / line-height
- 改变 display
- 改变内容(innerHTML / innerText / textContent)
- 添加或删除 DOM
- 移动 DOM(appendChild)
- 读取某些属性(强制同步布局)
例如:
scss
element.offsetHeight
element.clientWidth
getComputedStyle(element)
这些读取都会 强制刷新 Layout,非常耗性能。
✔ 改变以下会触发 Repaint(重绘)
- color
- background-image
- background-color
- border-color
- outline-color
- box-shadow
不改变布局的都属于 Repaint。
✔ 使用 transform/opacity 只触发 Composite(最快)
这是动画优化的核心:
css
transform: translateX(10px);
opacity: 0.5;
浏览器直接 GPU 合成,不会触发 Layout 或 Paint。
四、面试官常问陷阱(必须要会)
❓ 修改 transform 会触发重排吗?
不会。
❓ 修改 opacity 会触发重绘吗?
不会(通常只触发合成)。
❓ display: none 会触发什么?
- 隐藏:Reflow(布局被移除)
- 显示:Reflow(重新计算布局)
非常耗性能。
❓ visibility: hidden 会触发什么?
只触发 Repaint,不触发 Reflow。
❓ 哪些属性的读取会触发"强制同步布局"?
这题经常考。
例如:
scss
element.offsetWidth
element.offsetHeight
element.clientHeight
element.scrollTop
getComputedStyle(element)
这些会让浏览器 立即执行 Layout,非常卡。
五、性能优化策略(实战可用)
面试官常问:
如何减少 Reflow/Repaint?
✔ 1)批量 DOM 操作 → 使用 DocumentFragment
ini
const frag = document.createDocumentFragment();
for (...) {
frag.appendChild(...);
}
container.appendChild(frag);
避免多次 DOM 插入触发重排。
✔ 2)避免频繁读取布局属性(offsetHeight 等)
如果必须读取多次:
ini
const height = el.offsetHeight;
缓存下来。
✔ 3)将动画放到 Composite 层(transform/opacity)
css
.card {
will-change: transform, opacity;
}
浏览器会提前创建复合图层,极大提高动画性能。
✔ 4)避免一条条修改样式 → 使用 class 切换
css
.active { color: red; background: #fff; }
csharp
el.classList.add('active');
触发重排次数大幅减少。
✔ 5)避免使用 table 布局(极度昂贵)
table 的布局依赖整表结构,任何单元变化都会导致全表重排。
✔ 6)使用 requestAnimationFrame 做动画
setTimeout 会卡顿,因为和渲染时机不一致。
六、速记卡片(1 分钟复习)
🟦 浏览器渲染流程(Reflow / Repaint / Composite)
🔵 Reflow(重排)
- 影响布局(宽高、位置)
- 最耗性能
🔵 Repaint(重绘)
- 影响外观(颜色、阴影)
- 性能中等
🔵 Composite(合成层)
- transform / opacity
- 性能最好(GPU)
🟣 性能优化口诀
布局少改、样式少动、合成动画
要继续第 39 题吗?
👉 第 39 题:浏览器缓存策略(强缓存、协商缓存、缓存控制)