什么是关键渲染路径 (Critical Rendering Path)?
关键渲染路径 (Critical Rendering Path, CRP) 是浏览器将 HTML、CSS 和 JavaScript 代码转换为屏幕上实际像素的一系列步骤。
理解 CRP 对于前端性能优化至关重要。如果能缩短这一路径的处理时间,网页的首屏加载速度就会变快,用户就能更早地看到内容。
以下是关键渲染路径的详细流程分解:
CRP 的 6 个主要步骤
浏览器从服务器获取到 HTML 文档后,会按照以下顺序进行处理:
1. 构建 DOM 树 (Constructing the DOM Tree)
- 输入: HTML 文件。
- 过程: 浏览器读取 HTML 的原始字节,将其转换为字符,然后进行词法分析(Tokenization)生成节点(Nodes)。最后,这些节点链接在一起,形成了 文档对象模型 (DOM) 树。
- 注意: DOM 树描述了文档的内容。
2. 构建 CSSOM 树 (Constructing the CSSOM Tree)
- 输入: CSS 文件(外部样式表、内部样式块)。
- 过程: 浏览器解析 CSS,理解所有的样式规则(如
font-size,color等),并构建 CSS 对象模型 (CSSOM) 树。 - 注意: CSS 是阻塞渲染的资源。在 CSSOM 构建完成之前,浏览器不会进行渲染,因为这会导致页面先显示无样式内容(FOUC),然后突然闪烁变成有样式的样子。
3. 构建渲染树 (Constructing the Render Tree)
- 输入: DOM 树 + CSSOM 树。
- 过程: 浏览器将 DOM 和 CSSOM 结合。它会从 DOM 树的根节点开始遍历,只保留可见的节点。
- 不可见的节点(如
<head>、<meta>)会被忽略。 - 通过 CSS 设置为
display: none的节点也会被忽略(注意:visibility: hidden的节点仍在渲染树中,因为它占据空间)。
- 不可见的节点(如
- 产出: 渲染树包含了屏幕上将要显示的所有内容及其样式信息。
4. 布局 (Layout) —— 也称为 "回流" (Reflow)
- 任务: 计算几何信息。
- 过程: 浏览器根据渲染树,计算每个节点在屏幕上的确切位置和大小(以像素为单位)。
- 例子: 如果你设置
width: 50%,浏览器需要根据视口(Viewport)宽度计算出具体的像素值。
5. 绘制 (Paint)
- 任务: 填充像素。
- 过程: 浏览器将布局阶段计算出的每个盒子转换为屏幕上的实际像素。这包括绘制文本、颜色、图像、边框和阴影等。
- 注意: 绘制通常是在多个层(Layers)上完成的。
6. 合成 (Composite)
- 任务: 层叠组合。
- 过程: 浏览器将绘制好的各个图层按照正确的顺序(z-index 等)在 GPU 中合成,最终显示在屏幕上。
为什么 CRP 很重要?
性能优化的核心目标之一就是优化关键渲染路径。如果 CRP 太长或太复杂,用户就会看到白屏,导致跳出率增加。
如何优化关键渲染路径?
优化的核心策略通常概括为:减少、缩短、提前。
优化 CSS (CSS 是阻塞渲染的):
- 关键 CSS (Critical CSS): 将首屏必须的 CSS 直接内联写在 HTML 的
<style>标签中,这样浏览器无需等待外部 CSS 文件下载即可渲染首屏。 - 异步加载非关键 CSS: 对于首屏用不到的样式,使用
media属性或 JavaScript 延迟加载。 - 避免使用
@import,因为它会增加网络请求的往返次数。
- 关键 CSS (Critical CSS): 将首屏必须的 CSS 直接内联写在 HTML 的
优化 JavaScript (JS 会阻塞 DOM 构建):
- 当浏览器遇到
<script>标签时,会暂停构建 DOM,先下载并执行 JS。 - 使用
async或defer:defer: 脚本在 HTML 解析完成后执行(推荐)。async: 脚本下载完立即执行(可能打断 HTML 解析)。
- 将
<script>标签放在<body>底部。
- 当浏览器遇到
减少资源体积和请求数:
- 压缩 (Minify): 压缩 HTML、CSS 和 JS 文件,去除空格和注释。
- HTTP 缓存: 利用浏览器缓存,避免重复下载未更改的资源。
- 压缩图片: 图片虽然不阻塞 DOM 构建,但影响绘制和用户体验。
总结
关键渲染路径 = HTML/CSS/JS -> DOM/CSSOM -> 渲染树 -> 布局 -> 绘制。
作为开发者,你的目标是让浏览器尽可能快地走完前 5 步,让用户尽快看到页面的第一帧内容。