# 前端之DOM解析和渲染与CSS、JS之间的关系
每个前端在第一次写一个完整功能的页面,都可能会是这个样子滴~
<html>
<head>
<link rel="stylesheet" href="test.css">
</head>
<body>
<div id="app"></div>
<script src="test.js"></script>
</body>
2
3
4
5
6
7
8
9
我们都会被告知,css
要放到head
里面,js
要放到body
尾部前面。当然都能说出一二,但是我们还是有必要了解一下到底是为啥。
这里面有涉及到 DOM
,CSS
,JS
互相之间的一些关系,接下来会分别介绍
# DOM
TIP
DOM这里有两个概念,解析与渲染。
DOM解析:
就是把你所写的各种html
标签,生成一个DOM TREE
,可以认为就是生成了一个最原始的页面,一点样式都没有,毫无CSS
修饰的那种;DOM渲染:
浏览器会把本身默认的样式 + 用户自己写得样式整合到一起,形成一个CSS TREE
,而DOM
渲染就是指DOM TREE
和CSS TREE
结合到一起,生成一个Render TREE
,呈现出一个带有样式的页面。
# 线程
浏览器会有不同的线程,比如说
1. GUI
渲染线程
2. JS
线程
3. 定时器触发线程 (setTimeout
)
4. 浏览器事件线程 (onclick
)
5. http
异步线程
...
具体有关线程的内容,我会单独写一篇文章介绍,在这里我们只需要知道两点:
1. 上面的几个线程,在同一个瞬间,只有一个线程起作用,也就是互斥的。比如说浏览器在执行 GUI
渲染线程呢,那么其他的4个进程,都处于挂起的状态,在队列里面呆着。
2. DOM
的渲染对应的就是GUI
渲染进程;JS
的执行对应的就是JS
线程;所以,DOM
的渲染与JS
代码的运行,在同一瞬间只能有一个执行!
# 阻塞
阻塞XXX是指让XXX暂停了。比如JS
的执行阻塞DOM
解析,就是
DOM解析
--> JS执行
(此时DOM解析暂停) --> JS执行完毕
--> DOM继续解析
# DOM 与 CSS
先看它俩之间的关系,也就是分析CSS
的加载对DOM
的解析和渲染的影响。
很明显,DOM
自己在那解析 DOM TREE
和 css
样式有啥关系啊,所以css
不影响DOM
解析。
也很明显,DOM
渲染就是要生成样式呢,肯定和css
有关系啊,所以css
影响DOM
渲染。
结论
css
的加载不会阻塞DOM
的解析css
的加载会阻塞DOM
的渲染
# DOM 与 JS
JS(加载和执行) 都会阻塞 DOM
的解析,因为JS
中可能会对DOM
进行操作,可能改变DOM
的结构,所以JS
的加载和执行是会阻塞DOM解析的。
JS(加载和执行) 都会阻塞 DOM
的渲染,同上面一样,因为JS
中可能对样式进行操作。
# CSS 与 JS
在线程那里说了,CSS
的加载会阻塞JS
的执行,因为CSS
的渲染GUI
线程和JS
运行线程互斥。 但是CSS
不会阻塞JS
的加载(浏览器可以预先扫描并下载)
TIP
注1:
CSS
、JS
之间的加载是否阻塞,这里不考虑,因为现代的浏览器都会预先偷看文档,并且下载。
注2:
这里的JS
引入方式不包括 async
和 defer
结论:
CSS
的加载阻塞JS
的运行,不阻塞JS
的加载
# 三者
TIP
例1:
<header>
<link href="test.css">
</header>
2
3
加载test.css
是不会影响header
的解析的,只影响渲染
例2:
<header>
<link href="test.css">
<script src="test.js"></script>
</header>
2
3
4
加载test.css
阻塞了test.js
的运行,test.js
的运行阻塞了header
的解析和渲染,所以,看似test.css
既阻塞了header
的渲染,又阻塞了header
的解析。
# 总结
TIP
1. css
的加载不会阻塞DOM
的解析
2. css
的加载会阻塞DOM
的渲染
3. JS
的加载和执行会阻塞DOM
的解析
4. JS
的加载和执行会阻塞DOM
的渲染
5. CSS
的加载阻塞JS
的运行,不阻塞JS
的加载
6. CSS
的加载与JS
的加载之间是否有影响?不考虑,浏览器自身会偷看并预先下载
7. 遇到script
标签会触发渲染,以便获得最新的样式给JS
代码
~~