瀏覽器渲染網頁過程
想法丨發現丨習慣
同道者同行 同行者同享
我在文章《瀏覽器中輸入URL回車後...》中介紹了當在瀏覽器中輸入 URL 回車後客戶端如何找到伺服器並與之通信的過程。在客戶端與伺服器互相通信的過程中舉了客戶端向伺服器請求網頁資源的例子,那麼本章就詳細介紹當客戶端向伺服器請求到網頁資源後,瀏覽器渲染網頁的過程。
當請求到網頁資源後,瀏覽器便會開始渲染,渲染主要分為以下幾個步驟:
構建文檔對象模型(DOM);
構建 CSS 對象模型(CSSOM);
構建渲染樹(Render Tree);
布局(Layout);
繪製(Painting)。
上述步驟不是一個一次性執行完畢的過程,如果在渲染的過程中 DOM 或 CSSOM 被修改,則上述步驟會被重複執行。那麼接下來對上述五個步驟做一個詳細的說明~
構建文檔對象模型(DOM)
當瀏覽器從磁碟或網路中獲取到網頁(HTML 文件)的數據時,會通過一系列的轉換解析出各個 標籤,並最終構建文檔對象模型,即我們經常說的 DOM Tree,DOM Tree 的構建過程是一個深度遍歷的過程,當前節點的所有子節點構建好後才會去構建當前節點的下一個兄弟節點。
構建 CSS 對象模型(CSSOM)
在構建文檔對象模型的過程中,若遇到
標籤,則瀏覽器會發出一個獲取該資源的請求,最終獲得包含有各種 CSS 樣式的樣式文件。
與 HTML 文件一樣,瀏覽器會將該文件通過一系列的轉換和解析構建
出 CSS 對象模型,即 CSS Rule Tree。
構建渲染樹(Render Tree)
DOM Tree 描述的是文檔內容,而 CSS Rule Tree 描述的是應用於文檔的樣式規則,二者是獨立的對象。瀏覽器會把 DOM Tree 和 CSS Rule Tree 組合起來構建渲染樹,即 Render Tree。
從 DOM Tree 的根節點開始,遍歷每個可見的節點(某些不可見的節點如 標籤、 標籤等和某些通過 CSS 隱藏的節點不會體現在渲染結果中,因此會被忽略),為每一個可見的節點匹配並應用對應的 CSSOM 規則,生成有內容和計算樣式的可見節點的樹。
布局(Layout)
構建完渲染樹後,瀏覽器便會從渲染樹的根節點開始遍歷,計算頁面上每個對象的幾何信息,這一個過程稱為布局。布局輸出的是一個個「盒子模型」,它精確的計算出每個元素在視口中的準確位置及尺寸大小。
繪製(Painting)
最後一步是繪製,即將渲染樹中的每個節點繪製成實際的像素點。
關於迴流(Reflow)和重繪(Repaint)
渲染頁面的過程並不是一番風順的,經常會遇到元素的樣式被修改的情況,元素的樣式被修改後則會發生迴流和重繪。
迴流是指頁面中某些元素髮生變化而影響了布局時(如尺寸、位置改變),瀏覽器需要重新布局並繪製的過程。
重繪是指頁面中某些元素髮生了不影響布局的變化時(如顏色改變),瀏覽器重新繪製的過程。
由於迴流一定會包括重繪,所以迴流會更影響性能,在實際操作中,要盡量減少迴流。
引用總結
在網上看到一段對瀏覽器渲染網頁總結的一個有趣版本,在此引用,希望讓大家對瀏覽器渲染網頁的過程有一個更深刻的印象。
用戶輸入網址(假設是個 HTML 頁面,並且是第一次訪問),瀏覽器向伺服器發出請求,伺服器返回 HTML 文件;
瀏覽器開始載入代碼,發現 <head> 標籤內有一個 <link> 標籤引用外部 CSS 文件;
瀏覽器又發出 CSS 文件的請求,伺服器返回這個 CSS 文件;
瀏覽器繼續載入 HTML 中 <body> 部分的代碼,並且 CSS 文件已經拿到手了,可以開始渲染頁面了;
瀏覽器在代碼中發現一個 <img> 標籤引用了一張圖片,向伺服器發出請求,此時瀏覽器不會等到圖片下載完,而是繼續渲染後面的代碼;
伺服器返回圖片文件,由於圖片佔用了一定面積,影響了後面段落的排布,因此會發生迴流,瀏覽器需要回過頭來重新布局和繪製這部分元素;
瀏覽器發現了一個包含一行 JavaScript 代碼的 <script> 標籤,趕快運行它;
JavaScript 腳本執行了這條語句,它命令瀏覽器隱藏掉代碼中的某個 <div> (style.display=」none」),於是又發生了迴流,瀏覽器不得不重新布局和繪製這部分元素;
終於等到了 </html> 的到來,瀏覽器淚流滿面;
等等,還沒完,用戶點了一下界面中的「換膚」按鈕,JavaScript 讓瀏覽器換了一下 <link> 標籤的 CSS 路徑;
瀏覽器召集了在座的各位 <div><span><ul><li> 們,「大伙兒收拾收拾行李,咱得重新來過……」,瀏覽器向伺服器請求了新的 CSS 文件,重新渲染頁面。
TAG:淘淘笙悅 |