一、浏览器渲染流水线核心逻辑
浏览器从接收 HTML 字节到页面显示的全流程,核心分为5 个核心阶段 + 3 个关键优化点,逻辑是:
字节 → 结构化 → 样式化 → 布局 → 绘制 → 合成
每个阶段的输出是下一个阶段的输入,且前序阶段修改会触发后续阶段重新执行(性能优化关键)。
二、渲染流程拆解
1.阶段 1:解析 HTML → DOM 树(Parse HTML → DOM Tree)
- 输入:网络层传输的 HTML 字节(二进制);
- 处理:
- 浏览器先将字节转换为字符(UTF-8 解码);
- 词法分析:将字符拆分为「标签 / 属性 / 文本」等 Token(如
<div>、class="box"); - 语法分析:将 Token 组装为 DOM 节点,构建树形结构
(DOM Tree);
- 输出:DOM 树(描述 HTML 结构,每个节点对应文档中的元素 / 文本);
- 关键考点:
- 解析时遇到
<script>会阻塞 DOM 解析(需等待脚本执行 / 加载),可通过 async/defer 优化; - 遇到
<link rel="stylesheet">会阻塞渲染,但不阻塞 DOM 解析。
- 解析时遇到
2.阶段 2:解析 CSS → CSSOM 树(Parse CSS → CSSOM Tree)
- 输入:内联 CSS、外部 CSS 文件、
<style> 标签中的样式; - 处理:
- 同样经过「字节→字符→Token→节点」的解析过程;
- 解析 CSS 选择器、属性、值,构建 CSSOM 树(包含样式的继承、优先级规则);
- 输出:CSSOM 树(描述元素的样式规则,可计算每个 DOM 节点的最终样式);
- 关键考点:
- CSSOM 构建是阻塞渲染的(需等待所有 CSS 解析完成,才能计算样式);
- CSS 选择器从右向左匹配(如
box p先找所有 p,再筛选父级有.box的,这也是「避免复杂选择器」的原因)。
3. 阶段 3:样式计算(Style Calculation)
- 输入:DOM 树 + CSSOM 树;
- 处理:
- 为每个 DOM 节点匹配 CSSOM 中的样式规则;
- 计算节点的「计算样式」(Computed Style),解决样式冲突(如优先级、继承);
- 输出:带计算样式的 DOM 节点;
- 关键考点:
- !important、行内样式、ID 选择器等优先级会影响计算结果;
- 浏览器会缓存计算样式,仅修改样式时重新计算。
4. 阶段 4:布局(Layout / Reflow)
- 输入:带计算样式的 DOM 树;
- 处理:
- 计算每个节点的几何信息:位置(x/y)、尺寸(width/height)、盒模型;
- 构建布局树(Layout Tree),仅包含「可见节点」(隐藏节点如 display: none 会被排除);
- 输出:布局树(描述可见节点的几何位置);
- 关键考点:
- 布局是「流」式的,一个节点的布局变化会触发父 / 子 / 兄弟节点的重新布局(回流);
- 触发回流的操作:修改尺寸(width/height)、位置(top/left)、DOM 增删、窗口.resize 等。
5. 阶段 5:绘制(Paint)
- 输入:布局树;
- 处理:
- 将布局树转换为「绘制记录」(Paint Records),记录绘制顺序(如先画背景、再画文本、最后画边框);
- 浏览器将绘制记录提交给 GPU,绘制到图层上;
- 输出:像素信息(未显示到屏幕);
- 关键考点:
- 触发重绘的操作:修改颜色(color)、背景(background)、阴影(box-shadow)等不影响布局的样式;
- 重绘比回流性能消耗小,但仍需避免频繁触发。
6. 阶段 6:合成(Composite)
- 输入:各图层的像素信息;
- 处理:
- 浏览器将页面划分为多个图层(如 transform/opacity 会创建独立图层);
- GPU 对各图层进行合成,最终输出到屏幕;
- 输出:可见的页面;
- 关键考点:
- 合成阶段是性能最优的,修改 transform/opacity 仅触发合成,不触发回流 / 重绘;
- 合理使用图层(如 will-change: transform)可减少性能消耗。
三、渲染流程图
流程图如下:
- 阶段性能消耗对比表
| 阶段 | 性能消耗 | 触发操作示例 | 优化建议 |
|---|---|---|---|
| 回流(Layout) | 最高 | 修改 width/height、DOM 增删、resize | 1. 批量修改样式 2. 脱离文档流修改(position:absolute/fixed)3. 使用 requestAnimationFrame |
| 重绘(Paint) | 中等 | 修改 color、background、box-shadow | 1. 避免频繁修改可视样式 2. 合并样式修改 |
| 合成(Composite) | 最低 | 修改 transform、opacity | 优先使用这两个属性实现动画 |
总结
- 浏览器渲染流水线的核心是「从结构化到可视化」的递进过程,每个阶段的输出是下一个阶段的输入;
- 性能优化的关键是「减少阻塞」和「避免高频回流/重绘」,优先使用合成层属性(transform/opacity);