這篇文章源於公司內部的一次交流分享活動,選的主題都是些本身不瞭解的知識,而後經過學習研究再和同事分享。之因此選擇本身不瞭解的知識,也是爲了督促本身學習進步,而相應的因本人水平有限且初初接觸,文章中可能會存在某些不嚴謹的或者不正確的地方,望各位大神批評指正。原本定的主題是「預加載」,由於不瞭解,因此一再追本溯源,最後竟成了這關於瀏覽器渲染與阻塞的文章。css
瀏覽器有許多模塊,其中負責呈現頁面的是渲染引擎模塊,下圖爲Webkit渲染流程:html
雖然不一樣瀏覽器內核渲染細節有所不一樣,但基本思路類似:node
DOM和CSSOM是獨立的數據結構,其解析是兩個並行的進程,所以CSS加載不會阻塞DOM的解析。web
DOM樹和CSSOM樹的構建過程相似,下圖爲DOM樹的構建過程:面試
字節 → 字符 → 令牌 → 節點 → 對象模型瀏覽器
下圖爲渲染樹的生成過程:bash
注意,渲染樹只包含渲染網頁所需的節點微信
原文: zhuanlan.zhihu.com/p/24944905用一句話歸納就是: JS 全阻塞,CSS 半阻塞。
數據結構
- JS 會阻塞後續 DOM 解析以及其它資源(如 CSS,JS 或圖片資源)的加載。
- CSS 不會阻塞後續 DOM 結構的解析,不會阻塞其它資源(如圖片)的加載,可是會阻塞 JS 文件的加載。
- 現代瀏覽器很聰明,會進行 prefetch 優化,瀏覽器在得到 html 文檔以後會對頁面上引用的資源進行提早下載。(注意僅僅只是提早下載)
這是關於」阻塞「我精讀的第一篇文章,當初吸引個人一是歸納得很通俗易懂(如上),二是提供了一種實驗方式,這種方式很便於經過實驗增強對阻塞的理解,更是我第一次寫Node.js。dom
下圖是實驗的運行方式,前提是已經裝了node。
文章中的實驗很簡單,分析的也頗有道理的樣子,我覺得這一篇就能幫我搞定對」阻塞「的理解。然而,問題來了,看着實驗結果,有點懵,感受」阻塞「更難懂了。下圖爲文章demo的實驗結果:
看了實驗結果,感受跟文章中的結論對不上啊,下面是我產生的一系列疑問:
帶着疑惑我將index.html中的代碼作了以下修改,主要是按咱們更常見的方式將<link><script>標籤放在<head>標籤裏:
<head>
<script src="/yellow.js"></script> <!--5s-->
<link rel="stylesheet" href="/red.css"> <!--15s-->
<script src="/blue.js"></script> <!--10s-->
<link rel="stylesheet" href="/green.css"> <!--20s-->
</head>
<body>
<p>First Line</p>
<p>Second Line</p>
<p>Third Line</p>
<p>Fourth Line</p>
<p>Fifth Line</p>
</body>複製代碼
document.body.style.cssText = "background: blue !important";複製代碼
實驗現象:
實驗分析:
結合實驗2的實驗現象,和期間對相關資料的閱讀學習,對實驗1所在文章中的一些說法和實驗現象說說個人理解。
由於以前的js代碼都是經過link標籤引入的,這裏實驗3就直接將執行代碼寫進<script>標籤裏,但實際上,結果是同樣的。不少事情,只要明白原理,那麼就會一通百通啦~
<head>
<link rel="stylesheet" href="/red.css"><!-- wait="15s"-->
<script>
console.log('hello')
</script>
</head>複製代碼
經過實驗3能夠看出CSS阻塞了js的執行,那麼這是爲何呢?
個人拙見,其實和JS阻塞DOM解析是出於相同的考慮——爲了不衝突。JS阻塞DOM解析的緣由相信各位都知道,而JS代碼不只能夠操做DOM節點,也能夠操做CSSOM上的節點,所以也應該不能同時進行,要等到CSS加載完成。一樣的,JS執行也會阻止CSSOM的解析。可能有人會有點繞不明白,DOM解析和JS互斥執行時是JS阻塞了DOM解析,爲何CSSOM這裏確是CSS阻塞了JS?個人理解HTML解析是至上而下的,其生效順序也是至上而下、後者覆蓋前者,而不是下載完成順序,所以要等被阻塞JS的前面的CSS解析完才能執行,後面的就沒必要管了。
1)<head>裏
3)其餘(一些學來的知識點,只有結論,沒作實驗):
關鍵渲染路徑及其優化是個比較複雜的問題,感興趣的朋友們能夠點這裏。
舉個簡單的HTML+1個JS文件+1個CSS文件的例子以下:
上圖關鍵路徑特性爲:
研究了這麼多,固然是但願可以加快首屏加載速度,這裏從減小阻塞和優化關鍵三要素的角度提出一些優化建議。
<link href="print.css" rel="stylesheet" media="print">
<link href="other.css" rel="stylesheet" media="(min-width: 40em)">複製代碼
功能很強大的樣子,推薦你們看這裏,已經寫得很詳細了。