关键渲染路径
解释浏览器从 HTML 到像素的关键渲染路径,包括 DOM、CSSOM、Render Tree、Layout、Paint 各阶段。
#tech / dev / frontend
#type / concept
#status / growing
#resource / css
#platform / browser
[!info] related notes
- 所属 MOC: 前端基础 MOC, HTTP 与前端网络 MOC
- 前置概念: 浏览器渲染过程, 输入 URL 后发生了什么
- 并列概念: 首屏优化, HTTP 缓存, reflow-vs-repaint-interview-question
关键渲染路径
这篇笔记回答一个问题:浏览器拿到 HTML 后,经过哪些步骤才能把像素画到屏幕上。
一句话定义
关键渲染路径是浏览器将 HTML、CSS、JS 转换为屏幕上像素的一系列步骤,优化它的目标是尽快完成首次渲染。
核心阶段
1. 解析 HTML 构建 DOM
浏览器逐字节读取 HTML,将其转换为 DOM 树。遇到 <script> 时会阻塞解析(除非标记 async 或 defer)。
2. 解析 CSS 构建 CSSOM
CSS 解析生成 CSSOM 树。CSS 是渲染阻塞资源,浏览器必须等 CSSOM 构建完才能进入下一步。
3. 合并 DOM + CSSOM 生成 Render Tree
Render Tree 只包含可见节点。display: none 的节点不会出现在 Render Tree 中,但 visibility: hidden 的会。
4. Layout(布局)
计算 Render Tree 中每个节点的几何信息(位置、大小)。也叫 Reflow。
5. Paint(绘制)
将 Render Tree 节点填充像素,包括文字、颜色、边框、阴影等。
6. Composite(合成)
将多个图层合成为最终画面,由 GPU 加速。
关键渲染路径优化策略
- 减少关键资源数量:内联关键 CSS、异步加载非关键 JS
- 减少关键路径长度:减少资源请求链
- 减少关键资源大小:压缩、minify、tree-shaking
- 避免同步阻塞:script 用 async / defer,CSS 放在 head
常见边界
<link rel="stylesheet">阻塞渲染,<script>阻塞 HTML 解析@media查询不影响 CSSOM 构建,但影响是否下载该样式表display: none不参与 Render Tree,visibility: hidden参与但不显示- 频繁触发 Layout 的操作(如读取 offsetWidth 后修改样式)会导致强制同步重排
最小例子
<!DOCTYPE html>
<html>
<head>
<!-- 关键 CSS,内联减少请求 -->
<style>
body { font-family: sans-serif; }
.hero { font-size: 2rem; }
</style>
<!-- 非关键 CSS,异步加载 -->
<link rel="stylesheet" href="non-critical.css" media="print" onload="this.media='all'">
</head>
<body>
<h1 class="hero">Hello</h1>
<!-- defer 不阻塞解析 -->
<script defer src="app.js"></script>
</body>
</html>