從輸入URL到頁面加載 ——頁面渲染篇

前言

在Web相關的問題中,從輸入URL到整個頁面加載展現到用戶面前這個問題是繞不開的,它主要涉及到兩個步驟:web

  1. 網絡請求
  2. 頁面渲染
    1. 解析HTML文件,構建DOM樹
    2. 解析CSS文件,構建CSSOM樹
    3. 將DOM樹和CSSOM樹合併,生成渲染樹
    4. 計算渲染樹的佈局
    5. 將佈局渲染到屏幕上

本文主要介紹頁面渲染部分。編程


構建DOM樹

什麼是DOM樹?

DOM模型:HTML和XML文檔的編程接口。它提供了對文檔的結構化的表述,並定義了一種方式可使從程序中對該結構進行訪問,從而改變文檔的結構,樣式和內容。瀏覽器

DOM 將文檔解析爲一個由節點和對象(包含屬性和方法的對象)組成的結構集合。簡言之,它會將web頁面和腳本或程序語言鏈接起來。安全

DOM的結構是由各類子節點組成的,那麼以HTMLDocument爲根節點,其他節點爲子節點,那麼組織成的樹型數據結構的表示就是DOM樹。網絡

利用HTML解釋器構建DOM樹

HTML解釋器會將從網絡或者本地獲取的HTML文件解析成DOM樹。須要通過如下幾個步驟:數據結構

  1. 將字節流轉換成字符流,根據不一樣的編碼進行解碼
  2. 經過詞法分析將字符流解析爲一個個詞語(Token)。這個過程會跳過空格與換行內容。詞法分析由HTMLTokenizer完成。
  3. 使用XSSAuditor來進行詞語驗證及過濾,主要是出於安全方面的考慮
  4. 在通過XSSAuditor過濾以後,由解釋器調用方法構建DOM節點
  5. 從上面的DOM節點構建出來DOM樹,包括建立元素節點的屬性節點工做

在這裏插入圖片描述


構建CSSOM

什麼是CSSOM?

CSSOM(CSS對象模型)定義了媒體查詢、選擇器以及CSS自己的一系列API(包括通常的解析和序列化規則)。它是對附在DOM結構樹上的樣式的表達,與DOM樹的呈現方式類似,只是每一個節點都會帶上樣式屬性,包括明肯定義和隱式繼承的樣式。佈局

CSS是一種渲染阻塞資源(render blocking resource),它須要徹底被解析完畢以後才能進入生成渲染樹的環節性能

CSS並不像HTML那樣能執行部分並顯示,由於CSS具備繼承屬性, 後面定義的樣式會覆蓋或者修改前面的樣式。若是咱們只使用樣式表中部分解析好的樣式,咱們可能會獲得錯誤的頁面效果。因此,咱們只能等待CSS徹底解析以後,才能進入關鍵渲染路徑的下一環節。字體

在CSSOM構建完畢以前,頁面會一直處於白屏狀態,這也是爲何建議將CSS引用及<style>標籤放在head中,經過優先解析CSS,從而提升用戶體驗。優化

CSS解釋器

與處理HTML的邏輯同樣,CSS解釋器作的工做也是將收到的CSS文件轉換成瀏覽器可以理解處理的結構:

  1. 將字節流轉換成字符流
  2. 接着將字符流轉換成詞語(Token)
  3. 將Token轉換成相應的節點
  4. 最後組裝成CSSOM樹

阻塞頁面渲染

CSSOM樹在構建過程當中會阻塞頁面的渲染,可是不會阻塞DOM的解析

由於DOM樹與CSSOM樹的解析生成是獨立的,在生成過程當中無需阻塞DOM解析。

對於頁面渲染來講,若是CSSOM樹不進行阻塞,那會使頁面首先呈現出一個版本,在瀏覽器加載完畢CSSOM樹渲染後又變動了一個版本,用戶體驗不好,並且反覆渲染的成本也很高。


JavaScript解析

阻塞DOM的解析

JavaScript能夠操做DOM來修改DOM結構,所以在遇到外鏈腳本或者script標籤時,須要等待這部分代碼執行完成纔會繼續解析DOM。

通常如今的瀏覽器對這部分有作一些優化,在腳本阻塞時會繼續下載其餘資源,可是解析DOM的過程依然是阻塞的,只是優化了下載資源這個步驟。所以通常是建議將script標籤放在頁面底部。

同時也能夠經過增長defer屬性來改變腳本的執行特性,使其延遲執行:

  1. 瀏覽器下載HTML頁面,邊下載邊解析
  2. 解析過程當中發現帶有defer屬性的script標籤
  3. 網頁繼續下載解析,同時啓動script開始下載外部腳本
  4. 等待頁面渲染完成,執行下載的腳本

構建渲染樹

什麼是渲染樹?

當DOM樹與CSSOM樹構建完成後,瀏覽器會將二者進行結合,生成渲染樹,這棵樹包含了頁面全部可見元素及其渲染信息。


佈局

渲染樹生成以後,瀏覽器會根據渲染樹中的樣式以及設備的屏幕尺寸,來計算每一個元素的座標和大小。

迴流

若是頁面元素的結構、位置或者尺寸發生了變化,那麼就須要從新計算樣式並構建渲染樹。迴流的性能成本開銷是比較高的,通常開發時都須要儘可能避免頁面頻繁迴流。

引發迴流的操做:

  • 頁面初始化渲染
  • 刪除或者新增某個DOM節點
  • 修改頁面元素的尺寸值
  • 改變字體的大小
  • 獲取某些屬性值也會形成迴流:
    • offsetTop
    • scrollTop
    • clientTop
    • widthheight

繪製

計算最終的渲染信息,在實際的渲染過程當中瀏覽器會在儘量多的層上去渲染,相似於Photoshop裏圖層的概念。並將每一個渲染層進行合併,最終生成一層渲染畫面。在繪製過程當中,每一個層獨立渲染,並不關心與其餘層之間的關係。

相關文章
相關標籤/搜索