每個前端在第一次寫一個完整功能的頁面,都可能會是這個樣子滴~
<html>
<head>
<link rel="stylesheet" href="test.css">
</head>
<body>
<div id="app"></div>
<script src="test.js"></script>
</body>
</html>
複製程式碼
我們都會被告知,css要放到head裡面,js要放到body尾部前面。當然都能說出一二,但是我們還是有必要了解一下到底是為啥。
這裡面有涉及到 DOM,CSS,JS 互相之間的一些關係,接下來會分別介紹
DOM
DOM這裡有兩個概念,解析與渲染。
DOM解析:就是把你所寫的各種html標籤,生成一個DOM TREE,可以認為就是生成了一個最原始的頁面,一點樣式都沒有,毫無CSS修飾的那種;
DOM渲染:瀏覽器會把本身預設的樣式+使用者自己寫得樣式整合到一起,形成一個CSS TREE,而DOM渲染就是指DOM TREE 和 CSS TREE 結合到一起,生成一個Render TREE,呈現出一個帶有樣式的頁面。
執行緒
瀏覽器會有不同的執行緒,比如說
-
GUI 渲染執行緒
-
JS 執行緒
-
定時器觸發執行緒 (setTimeout)
-
瀏覽器事件執行緒 (onclick)
-
http 非同步執行緒
...
具體有關執行緒的內容,我會單獨寫一篇文章介紹,在這裡我們只需要知道兩點:
- 上面的幾個執行緒,在同一個瞬間,只有一個執行緒起作用,也就是互斥的。比如說瀏覽器在執行GUI 渲染執行緒呢,那麼其他的4個程式,都處於掛起的狀態,在佇列裡面呆著。
- 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中可能對樣式進行操作。
注: html中每遇到< script >標籤,頁面就會重新渲染一次,因為要保證標籤中的JS程式碼拿到的都是最新的樣式。
結論:
- JS的載入和執行會阻塞DOM的解析
- JS的載入和執行會阻塞DOM的渲染
CSS與JS
線上程那裡說了,CSS的載入會阻塞JS的執行,因為CSS的渲染GUI執行緒和JS執行執行緒互斥。 但是CSS不會阻塞JS的載入(瀏覽器可以預先掃描並下載)
注1:
CSS、JS之間的載入是否阻塞,這裡不考慮,因為現代的瀏覽器都會預先偷看文件,並且下載。
注2:
這裡的JS引入方式不包括async和defer
結論:
CSS的載入阻塞JS的執行,不阻塞JS的載入
三者
例1:
<header>
<link href="test.css">
</header>
複製程式碼
載入test.css是不會影響header的解析的,隻影響渲染
例2:
<header>
<link href="test.css">
<script src="test.js"></script>
</header>
複製程式碼
載入test.css阻塞了test.js的執行,test.js的執行阻塞了header的解析和渲染,所以,看似test.css既阻塞了header的渲染,又阻塞了header的解析。
總結
- css的載入不會阻塞DOM的解析
- css的載入會阻塞DOM的渲染
- JS的載入和執行會阻塞DOM的解析
- JS的載入和執行會阻塞DOM的渲染
- CSS的載入阻塞JS的執行,不阻塞JS的載入
- CSS的載入與JS的載入之間是否有影響?不考慮,瀏覽器自身會偷看並預先下載
- 遇到script標籤會觸發渲染,以便獲得最新的樣式給JS程式碼
~~
最後:若有錯誤之處,還請見諒,提出後會馬上修改~~~
轉載請註明出處,謝謝~~