页面在浏览器中渲染出来的原理和流程
# 整体流程
解析HTML,构建DOM树
解析CSS,生成CSS规则树
合并DOM树和CSS规则树,生成Render树(页面布局)
绘制Render树(paint),绘制页面像素信息
显示
# 拓展
JavaScript脚本由于可能会修改DOM,因此会阻塞DOM的构建,这一点我们都知道;而CSS并不会操作或者改变DOM,因此通常我们认为CSS不会影响DOM的构建,只会影响后续的布局、绘制等过程,即会影响DOM的渲染
。但其实CSS可以通过JavaScript来阻塞DOM的构建
。
因为JavaScript是可以改变样式的,也就是具有修改CSS规则树的能力,而JavaScript脚本里是否有改变样式的操作,这一点在执行JavaScript之前是不可知的
。因此,为保证JavaScript脚本的正确执行,在执行JavaScript之前,CSS规则树必须要先准备好(不然万一有修改CSS的操作呢)。
也就是说,若在构建DOM的中途存在阻塞DOM构建的JavaScript脚本,而此页面中还包含了外部 CSS 文件的引用,那么此时就需要等目前的CSS规则树(基于目前生成完的部分DOM树)构建完毕后,再开始JavaScript脚本的执行
,等一切结束了,再继续DOM的构建。
整个流程如图:(其中CSSOM表示CSS规则树)
示例代码:
<!DOCTYPE html>
<html lang="en">
<meta http-equiv="Content-Type" Content="text/html; Charset=UTF-8">
<head>
<style type="text/css">
h4{
font-size:18px;
font-weight:none;
}
</style>
<link rel="stylesheet" type="text/css" href="https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/static/protocol/https/soutu/css/soutu_new2_ae491b7.css">
</head>
<body>
<button id="btn">清空dom</button>
<div>我是div</div>
<!-- !!!script阻塞div的构建 -->
<script>
console.log('遇到内联script啦')
</script>
<div>我是div</div>
<div>我是div</div>
<div>我是div</div>
<div>我是div</div>
</body>
<script type="text/javascript">
let btn = document.getElementById('btn')
let body = document.body
btn.addEventListener("click", function(e){
body.innerHTML = ''
}, true);
</script>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# 参考文章链接
你不知道的浏览器页面渲染机制 (opens new window)
一名合格的初中级前端工程师需要掌握的浏览器渲染笔记 (opens new window)