浏览器从接收到服务器返回的HTML
到渲染像素到屏幕上,中间经历了很多的步骤。浏览器初次绘制网页的必经过程称之为“关键渲染路径(Critical Rendering Path
,以下称CRP
)”。
关键渲染路径
CRP
有以下6个阶段:
- 构造
DOM
树 - 构造
CSSOM
树 - 运行
JavaScript
- 创建渲染树(
Render Tree
) - 生成布局
- 绘制
一、构造 DOM 树
DOM
树是一个表示完整解析过的HTML
网页的对象。它从根元素<html>
开始,每一个节点代表页面上的一个元素或者文本。包含在其他元素中间的元素被表示成子节点。每一个节点记录着对应元素的所有属性,举例来说,一个 <a>
元素对应的节点包含了元素的href
属性。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<header> </header>
<section></section>
<footer></footer>
</body>
</html>
DOM 树
HTML
的一点好处是它可以分块执行,无需加载整个文档,内容就可以开始出现在页面上。但是不好的地方是,诸如CSS
和JavaScript
文件这样的资源,却能够阻塞页面的渲染。
二、构造 CSSOM 树
CSSOM
(CSS 对象模型
) 是一个表示DOM
相关联样式的对象。它与DOM
的表现方式类似,但记录了每个节点的关联样式,包含明确声明的样式和默认继承的样式。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header> </header>
<section></section>
<footer></footer>
</body>
</html>
/* style.css */
body {
font-size: 18px;
}
header {
color: plum;
}
section {
color: firebrick;
}
footer {
display: none;
}
CSSOM 树
CSS
文件只有适用于当前设备的时候才会被认为是 ”渲染阻塞资源“ 。<link rel="stylesheet">
标签可以接受一个媒体属性,通过改属性我们可以声明样式表适用的设备。例如:我们有个样式表声明了一个媒体属性orientation:landscape
, 只有我们在纵向模式访问的时候,该资源才是阻塞渲染的。
由于Javascript
文件必须等待CSSOM
构建完成才能够运行。因此也可以说CSS
是 “阻塞脚本”的。
三、运行 Javascript
JavaScript
被认为是一种 解析阻塞资源,HTML
本身的解析会被JavaScript
阻塞。
当解析器遇到<script>
标签时,不管是内部脚本还是外部脚本,解析器会停下来加载脚本(是外部脚本的情况下)并运行它。这就是为什么我们必须将哪些需要引用Element
和文档的脚本放在文档外观的后面。
为了避免 Javascript
阻塞解析,通过声明async
属性,可以让它被异步加载。
<script async src="script.js">
四、创建渲染树
渲染树是 DOM
和 CSSOM
的结合。它是一个表示页面被最终渲染效果的树。这意味着它只会表示哪些可见的内容,哪些不可见内容,比如声明了display:none;
的元素。
使用前面例子中提到的 DOM
和CSSDOM
,下面的渲染树会被创建出来。
五、生成布局
布局决定了视窗(viewport
)的大小,它提供了 CSS
样式依赖的上下文,例如视窗的百分比或者单位。
视窗的大小由在文档头部提供的meta
标签 viewport
决定,在移动端,如果不设置viewport
宽度为理想视口,viewport
宽度通常为980px
,这会导致文字很小,我们需要手动放大阅读。
举例,常用于响应设备宽度的视窗设置如下:
<meta name="viewport" content="width=device-width,initial-scale=1">
六、绘制
最终的步骤是绘制,页面的可见内容会被转化成屏幕上的像素。
绘制过程的耗时取决于DOM
的大小和应用的样式。某些样式比其他样式需要更多的处理过程。例如:复杂的渐变背景图比简单的填充背景需要消耗更多的处理时间。
网友评论