瀏覽器加載、解析、渲染的過程

剛看完一篇文章 How browsers work ,被裏面瀏覽器加載解析文件中標籤、CSS、javascript的順序搞暈了……

最初困惑我的是一張圖,下面這張。它解釋了瀏覽器解析、渲染的過程:解析HTML,構建dom樹  >  構建rander樹  >  佈局render樹  >  繪製render樹。但有一個細節引起了我的注意:這張圖片的起點不止一個,有 HTML解析 和 CSS解析,但瀏覽器是同步的呀,所以按照 “自上而下”的解析原則,應該是遇到誰解析誰唄? 


又翻到另一篇 博客 文章,結合起來理一下思路吧。

這段關於HTML頁面加載執行流程的描述挺有意思噠……

1. 用戶輸入網址(假設是個html頁面,並且是第一次訪問),瀏覽器向服務器發出請求,服務器返回html文件;

2. 瀏覽器開始載入html代碼,發現<head>標籤內有一個<link>標籤引用外部CSS文件;

3. 瀏覽器又發出CSS文件的請求,服務器返回這個CSS文件;

4. 瀏覽器繼續載入html中<body>部分的代碼,並且CSS文件已經拿到手了,可以開始渲染頁面了;

5. 瀏覽器在代碼中發現一個<img>標籤引用了一張圖片,向服務器發出請求。此時瀏覽器不會等到圖片下載完,而是繼續渲 染後面的代碼;

6. 服務器返回圖片文件,由於圖片佔用了一定面積,影響了後面段落的排布,因此瀏覽器需要回過頭來重新渲染這部分代碼;

7. 瀏覽器發現了一個包含一行Javascript代碼的<script>標籤,趕快運行它;

8. Javascript腳本執行了這條語句,它命令瀏覽器隱藏掉代碼中的某個<div> (style.display=”none”)。突然少了這麼一個元素,瀏覽器不得不重新渲染這部分代碼;

9. 終於等到了</html>的到來,瀏覽器淚流滿面……

10. 等等,還沒完,用戶點了一下界面中的“換膚”按鈕,Javascript讓瀏覽器換了一下<link>標籤的CSS路徑;

11. 瀏覽器召集了在座的各位<div><span><ul><li>們,“大夥兒收拾收拾行李,咱得重新來過……”,瀏覽器向服務器請求了新的CSS文件,重新渲染頁面。

所以……總結如下,歡迎拍磚。

1. 瀏覽器獲得一個HTML文件後,會 “自上而下” 開始加載,而且邊加載邊解析;

2. 考慮到用戶的體驗感,渲染引擎儘可能早地將內容呈現在屏幕上,瀏覽器不會等將html全部解析完後再構建render樹來呈現,而是邊解析邊顯示,其餘部分可以繼續下載;

3. 遇到<script>標籤,渲染引擎會將控制權交由script引擎來執行腳本。因爲腳本會通過DOM API操作DOM,如果一邊執行腳本一邊繼續構建DOM樹,二者會發生衝突;

4. 如果<script>引用了外部腳本,會停止document解析,轉去下載外部腳本並執行,此處也是同步的。如果外鏈的js腳本設置了defer=" true" 屬性(內置和動態生成的js腳本該屬性不起作用),此時文檔加載解析繼續進行,不會被阻塞,js代碼也會並行加載,但js會在所有元素解析完成以後,DOMContentLoaded事件觸發之前執行;

5. 如果外鏈的js腳本設置了async (異步) 屬性,加載js和渲染後續文檔過程並行進行(異步),一旦js腳本加載完畢就會立即執行。這種方式不能保證按書寫的順序執行,因爲瀏覽器解析到該屬性時會認爲該腳本不依賴其他的js和css;

6. 現在許多瀏覽器做了優化。當javascript引擎執行js腳本時,瀏覽器會開啓其他線程繼續解析下面的文檔,發現其餘需要下載的外部資源,如圖片、外部js、樣式表等,這些下載也是並行進行的;

7. 樣式表在加載解析時會阻塞js的執行。雖然css (一般只會出現在head中) 並不會改變DOM結構,但js執行過程中可能會請求樣式信息,如果二者同時執行js會得到錯誤信息,所以js會在前面的樣式表全部解析完後再開始執行。但有一點,外鏈的css和js是並行下載的。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章