浏览器接收到服务器返回的 HTML
、CSS
和 JavaScript
字节数据并对其进行解析和转变成像素的渲染过程被称为关键渲染路径。通过优化关键渲染路径即可以缩短浏览器渲染页面的时间。
浏览器渲染页面前需要先构建 DOM
和 CSSOM
树。因此,我们需要确保尽快将 HTML
和 CSS
都提供给浏览器。
文档对象模型 (DOM)
先看一下浏览器是如何构建 DOM
的:
- 转换: 浏览器从磁盘或网络读取
HTML
的原始字节,并根据文件的指定编码(例如UTF-8
)将它们转换成各个字符。 - 令牌化: 浏览器将字符串转换成
W3C HTML5
标准规定的各种令牌,例如,<html>
、<body>
,以及其他尖括号内的字符串。每个令牌都具有特殊含义和一组规则。 - 词法分析: 发出的令牌转换成定义其属性和规则的“对象”。
DOM
构建: 最后,由于HTML
标记定义不同标记之间的关系(一些标记包含在其他标记内),创建的对象链接在一个树数据结构内,此结构也会捕获原始标记中定义的父项-子项关系:HTML
对象是body
对象的父项,body
是paragraph
对象的父项,依此类推。
CSS 对象模型 (CSSOM)
与处理 HTML
时一样,我们需要将收到的 CSS
规则转换成某种浏览器能够理解和处理的东西。因此,我们会重复 HTML
过程,不过是为 CSS
而不是 HTML
:
这就是构建 CSSOM
树的过程。
构建渲染树
我们根据 HTML
和 CSS
输入构建了 DOM
树和 CSSOM
树。不过,它们都是独立的对象,分别网罗文档不同方面的信息:一个描述内容,另一个则是描述需要对文档应用的样式规则。需要将二者结合生成渲染树才是渲染到屏幕上的东西。
为构建渲染树,浏览器大体上完成了下列工作:
1.从 DOM
树的根节点开始遍历每个可见节点。
- 某些节点不可见(例如脚本标记、元标记等),因为它们不会体现在渲染输出中,所以会被忽略。
- 某些节点通过
CSS
隐藏,因此在渲染树中也会被忽略,例如,上例中的span
节点—不会出现在渲染树中,—因为有一个显式规则在该节点上设置了display: none
属性。(值得注意的是visibility: hidden
属性并不算是不可见属性,它的语义是隐藏元素,但元素仍然占据着布局空间,所以它会被渲染成一个空框)
2.对于每个可见节点,为其找到适配的 CSSOM
规则并应用它们。
3.发射可见节点,连同其内容和计算的样式。
渲染树构建完毕后,浏览器得到了每个可见节点的内容与其样式,下一步工作则需要计算每个节点在窗口内的确切位置与大小,也就是 布局阶段。
布局阶段会从渲染树的根节点开始遍历,然后确定每个节点对象在页面上的确切大小与位置,布局阶段的输出是一个盒子模型,它会精确地捕获每个元素在屏幕内的确切位置与大小,所有相对的测量值也都会被转换为屏幕内的绝对像素值。
关键渲染路径
1.处理 HTML 标记并构建 DOM 树。
2.处理 CSS 标记并构建 CSSOM 树。
3.将 DOM 与 CSSOM 合并成一个渲染树。
4.根据渲染树来布局,以计算每个节点的几何信息。
5.将各个节点绘制到屏幕上。
优化关键渲染路径_就是指最大限度缩短执行上述第 1 步至第 5 步耗费的总时间
阻塞渲染的 CSS
CSS
是阻塞渲染的资源。需要将它尽早、尽快地下载到客户端,以便缩短首次渲染的时间。
通过使用媒体查询,我们可以根据特定用例(比如显示或打印),也可以根据动态情况(比如屏幕方向变化、尺寸调整事件等)定制外观。声明样式表资产时,请密切注意媒体类型和查询,因为它们将严重影响关键渲染路径的性能。
1 | <link href="style.css" rel="stylesheet"> |
像上面的第一个适用所有情况,故而会阻塞渲染;而第二个和第三个分别适应打印时和屏幕宽度大于 40em
时,所以不会阻塞渲染。
请注意“阻塞渲染”仅是指浏览器是否需要暂停网页的首次渲染,直至该资源准备就绪。无论哪一种情况,浏览器仍会下载
CSS
资源,只不过不阻塞渲染的资源优先级较低罢了。
优化 JavaScript
JavaScript
可以查询和修改DOM
与CSSOM
。JavaScript
执行会阻止CSSOM
。- 除非将
JavaScript
显式声明为异步,否则它会阻止构建DOM
。
可以将脚本标记为异步防止阻塞 DOM
和 CSSOM
构建:
1 | <script src="app.js" async></script> |
优化关键渲染路径总结
关键资源:可能阻塞网页首次渲染的资源。
关键路径长度:获取关键资源所需的往返次数或总时间。
关键字节:所有关键资源文件大小的总和。
优化关键渲染路径就是在对关键资源、关键路径长度和关键字节进行优化。关键资源越少,浏览器在渲染前的准备工作就越少;同样,关键路径长度和关键字节关系到浏览器下载资源的效率,它们越少,浏览器下载资源的速度就越快。
评估关键渲染路径可以使用
Lighthouse
审核页面,参阅 使用 Lighthouse 审核网络应用。
PageSpeed 规则和建议
优化
JavaScript
的使用
避免同步服务器调用
延迟解析JavaScript
,async
和defer
避免运行时间长的JavaScript
优化 CSS 的使用
将CSS
置于文档head
标签内,尽早下载
避免使用CSS import
,它们会在关键路径中增加往返次数
内联阻塞渲染的CSS
,这样不会增加关键路径中增加往返次数