一、整体流程(核心主线)
浏览器渲染页面大致分为 5 个阶段:
1. 解析 HTML → 构建 DOM
2. 解析 CSS → 构建 CSSOM
3. 合并 DOM + CSSOM → Render Tree
4. Layout(布局 / 回流)
5. Paint(绘制) → Composite(合成)
二、详细拆解每一步
1️⃣ HTML 解析 → DOM 树
浏览器拿到 HTML 后:
- 从上到下解析(流式解析)
- 遇到标签 → 转成节点(Node)
- 最终形成 DOM 树
👉 特点:
- 同步解析
- 遇到
<script>默认会阻塞解析(除非 async / defer)
2️⃣ CSS 解析 → CSSOM 树
- 解析 CSS 文件和
<style> - 生成 CSSOM(CSS Object Model)
👉 注意:
- CSS 是 阻塞渲染的(render blocking)
- 因为浏览器必须知道样式才能绘制
3️⃣ 构建 Render Tree(渲染树)
将:
DOM + CSSOM → Render Tree
👉 特点:
-
只包含 可见节点
display: none❌ 不会进入
-
每个节点都有样式信息
4️⃣ Layout(布局 / 回流 Reflow)
计算每个元素的位置和大小:
- width / height
- margin / padding
- position
👉 结果:
确定每个元素在屏幕上的精确位置
👉 会触发 Reflow 的操作:
- 修改 DOM
- 改变元素尺寸
- 改变字体大小
- 获取布局信息(如 offsetTop)
5️⃣ Paint(绘制)
将布局后的节点:
- 转换成像素
- 绘制颜色、边框、阴影、文字
6️⃣ Composite(合成)
- 页面被分成多个 图层(layers)
- GPU 进行合成
- 最终显示到屏幕
👉 常见触发新图层:
transformopacitywill-changeposition: fixed
三、重点机制(面试必问🔥)
✅ 1. 回流(Reflow) vs 重绘(Repaint)
| 类型 | 影响 |
|---|---|
| Reflow | 重新计算布局(最贵) |
| Repaint | 只改样式,不影响布局 |
👉 举例:
div.style.width = '200px' // Reflow
div.style.color = 'red' // Repaint
✅ 2. 为什么 CSS 会阻塞渲染?
因为:
👉 浏览器必须确保:
DOM + CSSOM → Render Tree 正确
否则页面会出现:
- 闪烁(FOUC)
- 样式错乱
✅ 3. JS 为什么会阻塞?
默认 <script>:
- 会暂停 HTML 解析
- 因为 JS 可能修改 DOM
👉 解决方案:
<script defer></script> // HTML解析完再执行
<script async></script> // 下载完立即执行(不保证顺序)
✅ 4. GPU 加速(性能优化关键)
transform: translateZ(0);
👉 作用:
- 创建独立图层
- 避免 Reflow
- 提高动画性能
四、性能优化总结(实战)
🚀 减少 Reflow
- 批量修改 DOM
- 使用
documentFragment - 避免频繁读取 layout 属性
🚀 使用合成层优化动画
优先用:
transform
opacity
避免:
width
height
top
left
🚀 CSS / JS 优化
- CSS 放头部
- JS 放底部或用 defer
- 减少 CSS 层级
五、一句话总结(面试版)
👉 浏览器渲染流程:
HTML → DOM
CSS → CSSOM
DOM + CSSOM → Render Tree
Layout → Paint → Composite