瀏覽器加載解析過程
為了搞清楚js css到底在頁面加載的哪個環節中被執行使用了,就找了一些文章看了下,感覺沒有理解的很透徹,但也比之前有更近一步認識。
解析html以構建dom樹 -> 構建render樹 -> 布局render樹 -> 繪制render樹
上面這個流程是最基本的了,但實際上從文檔被請求回來之後,一步步的執行,結合幾個比較重要的點,我自己理解如下,若有問題,望指正:
重要點:
最重要的:渲染引擎將會盡可能早的將內容呈現到屏幕上,並不會等到所有的html都解析完成之後再去構建和布局render樹。它是解析完一部分內容就顯示一部分內容,同時,可能還在通過網絡下載其余內容。
dom的解析是深度遍歷,所有子元素遍歷完後,在解析下一個兄弟元素
css的選擇符從右到左解析。
所以當文檔從上到下解析的時候,
1、若遇到css,則構建css rule tree,
2、若遇到html標簽,則構建dom tree,
3、若遇到js,則什麽都不幹,等js解析執行完成,js可能在此階段修改dom tree 或css rule tree,瀏覽器希望等所有的都定下來後,再往下走。
-------以上為構建dom
4、然後等到某一部分內容都解析完成了,比如一個<div>...</div>這裏所有的內容都解析完了,就利用這部分內容的相關的dom tree 和 css rule tree 生成一個render樹(此過程中會將一些display none的元素幹掉),
--------以上為構建render樹
5、瀏覽器開始為每個元素定位
--------以上為布局render樹
6、然後通過瀏覽器的繪制展現實際的元素給用戶。
--------以上為繪制render樹
7、然後瀏覽器接著往下執行,在後面的任何地方,若有對之前渲染過的部分有(布局)影響,就reflow之前的布局,重新走一遍流程,若只是對顏色等做了修改,不影響布局,則repain;reflow性能比repain 低。
了解後的啟發:
js要放在最後,
css選擇符從右到左尋找,故盡量使用子選擇符 #tp > p{},而不是後代選擇符 #tp p,更不要用通配符*
dom的結構,盡量減少嵌套深度
對於動畫的部分(頻繁修改的dom元素),采用脫離文檔流的布局(fixed absoult),避免reflow
盡量用css類來定義或改變dom元素的樣式,而不是直接對dom進行一個個屬性設置,減少repain次數
盡量給圖片等元素加上寬高,因為圖片請求加載後,瀏覽器繼續渲染,等圖片回來後,寬高變了,影響了布局,瀏覽器不得不對這部分內容進行reflow,
瀏覽器加載解析過程