用户在使用浏览器访问一个网站时需要先通过HTTP(HTTPS)协议向服务器发送请求,之后服务器返回HTML文件与响应信息。这时,浏览器会根据HTML文件来进行解析与渲染(该阶段还包括向服务器请求非内联的CSS文件与JavaScript文件或者其他资源),最终再将页面呈现在用户面前。
关键渲染路径
览器接收到服务器返回的HTML、CSS和JavaScript字节数据并对其进行解析和转变成像素的渲染过程被称为关键渲染路径
浏览器在渲染页面前需要先构建出DOM树与CSSOM树(如果没有DOM树和CSSOM树就无法确定页面的结构与样式,所以这两项是必须先构建出来的)
构建DOM树
DOM树全称为Document Object Model文档对象模型,它是HTML和XML文档的编程接口,提供了对文档的结构化表示,并定义了一种可以使程序对该结构进行访问的方式(比如JavaScript就是通过DOM来操作结构、样式和内容)。DOM将文档解析为一个由节点和对象组成的集合,可以说一个WEB页面其实就是一个DOM。
浏览器从网络或硬盘中获得HTML字节数据后会经过一个流程将字节解析为DOM树: 字节 -> 字符 -> 令牌 -> 节点对象 -> 对象模型
下面通过一个例子来清晰地展示整个过程
<head>
<meta name="viewport" content="width=device-width,initial-scale=1">
<link href="style.css" rel="stylesheet">
<title>Critical Path</title>
</head>
<body>
<p>Hello <span>web performance</span> students!</p>
<div><img src="awesome-photo.jpg"></div>
</body>
</html>
构建CSSOM树
CSSOM树全称为Cascading Style Sheets Object Model层叠样式表对象模型,它与DOM树的含义相差不大,只不过它是CSS的对象集合.
当在构建DOM树的过程中, 如果遇到<link>
标签, 浏览器会发送请求获得该标签中标记的CSS文件(使用内联CSS可以省略请求的步骤提高速度,但没有必要为了这点速度而丢失了模块化与可维护性, style.css
中的内容如下:
body { font-size: 16px }
p { font-weight: bold }
span { color: red }
p span { display: none }
img { float: right }
浏览器获得外部CSS文件的数据后,就会像构建DOM树一样开始构建CSSOM树.
构建渲染树
在构建了DOM树和CSSOM树之后,浏览器只是拥有了两个互相独立的对象集合,DOM树描述了文档的结构与内容,CSSOM树则描述了对文档应用的样式规则,想要渲染出页面,就需要将DOM树与CSSOM树结合在一起,这就是渲染树.
浏览器会先从DOM树的根节点开始遍历每个可见节点(不可见的节点自然就没必要渲染到页面了,不可见的节点还包括被CSS设置了
display: none
属性的节点,值得注意的是visibility: hidden
属性并不算是不可见属性,它的语义是隐藏元素,但元素仍然占据着布局空间,所以它会被渲染成一个空框)对每个可见节点,找到其适配的CSS样式规则并应用
渲染树构建完成,每个节点都是可见节点并且都含有其内容和对应规则的样式
布局
布局阶段工作则需要计算每个节点在窗口内的确切位置与大小.
CSS采用了一种叫做盒子模型的思维模型来表示每个节点与其他元素之间的距离,盒子模型包括外边距(Margin),内边距(Padding),边框(Border),内容(Content)。页面中的每个标签其实都是一个个盒子.
布局阶段会从渲染树的根节点开始遍历,然后确定每个节点对象在页面上的确切大小与位置,布局阶段的输出是一个盒子模型,它会精确地捕获每个元素在屏幕内的确切位置与大小,所有相对的测量值也都会被转换为屏幕内的绝对像素值.
绘制
当Layout布局事件完成后,浏览器会立即发出Paint Setup与Paint事件,开始将渲染树绘制成像素,绘制所需的时间跟CSS样式的复杂度成正比,绘制完成后,用户就可以看到页面的最终呈现效果了.
总结
- 解析html标签, 构建DOM树
- 解析css标签, 构建CSSOM树
- 把DOM和CSSOM组合成 渲染树(render tree)
- 在渲染树基础上进行布局, 计算每个节点的几何结构
- 把每个节点绘制到屏幕上
值得注意的是,这个过程是逐步完成的,为了更好的用户体验,渲染引擎将会尽可能早的将内容呈现到屏幕上,并不会等到所有的html都解析完成之后再去构建和布局render树。它是解析完一部分内容就显示一部分内容,同时,可能还在通过网络下载其余内容.