<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> </body> </html>
一個簡單的html頁面如上所示。css
DOM有兩個概念:html
DOM解析:就是把你所寫的各類html標籤,生成一個DOM TREE,能夠認爲就是生成了一個最原始的頁面,一點樣式都沒有,毫無CSS修飾。web
DOM渲染:瀏覽器會把自己默認的樣式+用戶本身寫得樣式整合到一塊兒,造成一個CSS TREE,而DOM渲染就是指DOM TREE 和 CSS TREE 結合到一塊兒,生成一個Render TREE,呈現出一個帶有樣式的頁面。瀏覽器
1)瀏覽器會解析三個東西:多線程
一個是HTML/SVG/XHTML,事實上,Webkit有三個C++的類對應這三類文檔。解析這三種文件會產生一個DOM Tree。
CSS,解析CSS會產生CSS規則樹。
Javascript,腳本,主要是經過DOM API和CSSOM API來操做DOM Tree和CSS Rule Tree.
2)解析完成後,瀏覽器引擎會經過DOM Tree 和 CSS Rule Tree 來構造 Rendering Tree。注意:異步
Rendering Tree 渲染樹並不等同於DOM樹,由於一些像Header或display:none的東西就不必放在渲染樹中了。
CSS 的 Rule Tree主要是爲了完成匹配並把CSS Rule附加上Rendering Tree上的每一個Element。也就是DOM結點。也就是所謂的Frame。
而後,計算每一個Frame(也就是每一個Element)的位置,這又叫layout和reflow過程。
3)最後經過調用操做系統Native GUI的API繪製。async
js 是單線程,可是瀏覽器是多線程的。佈局
瀏覽器會有不一樣的線程,好比說優化
上面的幾個線程,在同一個瞬間,只有一個線程起做用,也就是互斥的。好比說瀏覽器在執行GUI 渲染線程呢,那麼其餘的4個進程,都處於掛起的狀態,在隊列裏面呆着。
DOM的渲染對應的就是GUI渲染進程;JS的執行對應的就是JS線程;因此,DOM的渲染與JS代碼的運行,在同一瞬間只能有一個執行!ui
阻塞XXX是指讓XXX暫停了。好比JS的執行阻塞DOM解析,就是
DOM解析 --> JS執行(此時DOM解析暫停) --> JS執行完畢 --> DOM繼續解析
先看它倆之間的關係,也就是分析CSS的加載對DOM的解析和渲染的影響。
很明顯,DOM本身在那解析DOM TREE 和 css樣式有啥關係啊,因此css不影響DOM解析。
也很明顯,DOM渲染就是要生成樣式呢,確定和css有關係啊,因此css影響DOM渲染。
結論:
JS(加載和執行) 都會阻塞 DOM 的解析,由於JS中可能會對DOM進行操做,可能改變DOM的結構,因此JS的加載和執行是會阻塞DOM解析的。
JS(加載和執行) 都會阻塞 DOM 的渲染,同上面同樣,由於JS中可能對樣式進行操做。
注: html中每遇到< script >標籤,頁面就會從新渲染一次,由於要保證標籤中的JS代碼拿到的都是最新的樣式。
結論:
在線程那裏說了,CSS的加載會阻塞JS的執行,由於CSS的渲染GUI線程和JS運行線程互斥。
可是CSS不會阻塞JS的加載(瀏覽器能夠預先掃描並下載)
注1:
注2:
結論:
Note: 簡單提一句,請注意 visibility: hidden 與 display: none 是不同的。前者隱藏元素,但元素仍佔據着佈局空間(即將其渲染成一個空框),然後者 (display: none) 將元素從渲染樹中徹底移除,元素既不可見,也不是佈局的組成部分。
下面簡要概述了瀏覽器完成的步驟:
優化關鍵渲染路徑_就是指最大限度縮短執行上述第 1 步至第 5 步耗費的總時間
https://developers.google.com...