理解『Critical Rendering Path』

image

想要更好的处理网页性能,就要对关键渲染路径(Critical Rendering Path)有所了解。

从浏览器接受到服务端返回的html代码到我们能在屏幕上看到最终的渲染效果会经过很多步骤。这一系列浏览器运行的步骤到绘制页面结束的过程被称为Critical Rendering Path

了解CRP有助于了解如何提醒网站的性能。CRP会经历以下6个步骤:

  • 构建DOM树
  • 构建CSSOM树
  • 运行javascript
  • 创建渲染树
  • 生成布局
  • 绘制

CRP-Sequence

➤ 构建DOM树

DOM(Document Object Model)树是一个代表完全解析HTML页面的对象,从根元素<html>开始,同时为页面上的每个元素/文本创建节点。嵌套在其他元素中的元素表示为子节点,每个节点包含该元素的全部属性。例如:一个<a>元素在他的节点上可以相连href属性。示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

<html>
<head>
<title>Understanding the Critical Rendering Path</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header>
<h1>Understanding the Critical Rendering Path</h1>
</header>
<main>
<h2>Introduction</h2>
<p>Lorem ipsum dolor sit amet</p>
</main>
<footer>
<small>Copyright 2017</small>
</footer>
</body>
</html>

会生成如下DOM树:

DOM

可喜的是HTML可以部分执行,不需要等到完整的文档解析完才开始加载内容到页面上。但是其他资源,比如(css\javascript)会阻断页面的渲染。

➤ 构建CSSOM树

CSSOM(CSS Object Model)是一个表示DOM和样式关联的对象。类似于DOM,但是每一个节点增加了关联的样式(无论它们是显式声明还是隐式继承)。

style.css中,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
body {
font-size: 18px;
}
header {
color: plum;
}
h1 {
font-size: 28px;
}
main {
color: firebrick;
}
h2 {
font-size: 20px;
}
footer {
display: none;
}

构建的CSSOM树如下:

CSSOM

css被认为是一种渲染阻塞的资源(render blocking resource)。这意味着如果不首先完全解析css,渲染树无法构建。与HTML不同,由于继承、级联特性css不能部分执行,在文档中预先定义的样式可以被重写和更改。所以,如果我们开始使用css样式定义在样式表之前全部解析完毕,那么可能结果不是我们所预期的,这意味着必须充分解析CSS才能进入下一个阶段。

css是否会阻断页面的的渲染还跟当前的设备有关。<link rel="stylesheet">标签可以接受一个media属性,该属性能限定某一种媒体查询下才应用css。假如有orientation:landscape属性添加,那么在横屏模式下,资源不会阻塞页面渲染。

css同时也会阻塞脚本。这是因为JavaScript文件必须等到CSSOM之前才能运行。

➤ 运行javascript

javascript被认为是一种解析器阻塞资源。这意味着解析HTML文档本身被JavaScript阻塞。当解析器发现一个<script>标签时候,无论是内部或外部,解析器都会停止解析并去获取(如果它是外部的)和运行脚本。这就是为什么通常我们建议把脚本代码放到页面最后。

为了避免JavaScript解析器的阻塞,它可以使用async属性异步加载。

1
<script async src="script.js">

➤ 创建渲染树

渲染树是DOMCSSOM的结合,它代表最终将在页面上呈现的内容。这意味着它只捕获可见的内容,并且不包括隐藏的DOM比如添加了display: noneDOM不会被渲染。

Render-Tree

➤ 生成布局

布局决定提供了CSS样式所依赖的上下文视口的大小。如百分比或视口的单位,视口的大小是由元视口标签在文件头上确定,如果没有提供标签默认为980px。例如,最常见的元价值是设置视口视口大小对应的设备宽度:

1
<meta name="viewport" content="width=device-width,initial-scale=1">

➤ 绘制

在绘画步骤中,页面的可见内容可以转换为屏幕上显示的像素。绘制所需要的时间依赖于DOM大小以及什么风格样式。有些样式需要更多的工作来执行,比如一个复杂的渐变背景图像将需要更多的时间比一个简单的固体背景颜色。

可以使用chrome开发工具查看页面的渲染过程:F12–>Timeline–>EventLog

Timeline

可以看出,简单的页面包含以下步骤:

  • 1、Send Request: 从服务端获取html
  • 2、Parse HTML and Send Request:开始解析HTML和DOM结构。并发起请求获取css,js文件
  • 3、Parse Stylesheet: 解析css
  • 4、Evaluate Script: 计算脚本
  • 5、Layout: 生成布局
  • 6、Paint: 绘制

➤ 总结

理解好以上内容才能更准确的对网站进行性能优化。