瀏覽器渲染過程與原理淺析(一)

不會音樂的肖邦發表於2018-03-29
     我為啥要知道瀏覽器渲染過程,嗯...面試會問....但最重要的是瞭解它工作原理,讓你在弄它時,遊刃有餘。

先看下瀏覽器有什麼。

瀏覽器的主要元件為:

  1. 使用者介面 - 除了瀏覽器主視窗顯示的您請求的頁面外,其他顯示的各個部分都屬於使用者介面。
  2. 瀏覽器引擎 - 在使用者介面和呈現引擎之間傳送指令。
  3. 呈現引擎 - 負責顯示請求的內容。如果請求的內容是 HTML,它就負責解析 HTML 和 CSS 內容,並將解析後的內容顯示在螢幕上。
  4. 網路 - 用於網路呼叫,比如 HTTP 請求。其介面與平臺無關,併為所有平臺提供底層實現。
  5. 使用者介面後端 - 用於繪製基本的視窗小部件,比如組合框和視窗。其公開了與平臺無關的通用介面,而在底層使用作業系統的使用者介面方法。
  6. JavaScript 直譯器-用於解析和執行 JavaScript 程式碼。
  7. 資料儲存-這是持久層。瀏覽器需要在硬碟上儲存各種資料,例如cookie。瀏覽器還支援諸如localStorage,IndexedDB,WebSQL和FileSystem之類的儲存機制。
      瀏覽器(如Chrome)執行渲染引擎的多個例項時:每個選項卡都在單獨的程式中執行。

從網路請求到HTML資料,並顯示頁面的流程:瀏覽器渲染過程與原理淺析(一)
     當網頁訪問並接受到返回資料時,瀏覽器會嘗試解析(為HTML)。
     獲取返回的資料流後,第一步進行讀取解析,後面會進行的編譯HTML到DOM佈局呈現,這都是呈現引擎需要做的事情。
呈現引擎所做的事:瀏覽器渲染過程與原理淺析(一)

      對於呈現引擎來說,這是漸進的過程。 在不斷接收和處理來自網路的其餘內容的同時,呈現引擎會將部分內容解析並顯示出來。

瀏覽器核心不同,解析的流程有可能會不一樣(以WebKit與Mozilla 的 Gecko 為例):

瀏覽器渲染過程與原理淺析(一)

瀏覽器渲染過程與原理淺析(一)

可以看到 Gecko 解析的流程多於WebKit,並在官方的術語上有著些許不同,另外呈現樹與DOM樹不一定相同,後面會做說明。

HTML解析器的輸出“解析樹”是由 DOM 元素和屬性節點構成的樹結構,DOM 是文件物件模型 (Document Object Model) 的縮寫。也會有外部內容(例如 JavaScript)與 HTML 元素之間的介面。
一個HTML的例子來說明DOM樹:

<html>   
 <body>
    <p>       
     Hello World        
    </p>        
    <div><img src="example.png"/></div>    
    </body>
</html>複製程式碼
生成的DOM樹:

瀏覽器渲染過程與原理淺析(一)

HTML 的標記化演算法:
      在呈現引擎中,為了構建DOM樹,HTML解析器需要使用標記化演算法,對HTML文件進行解析。
      標記化演算法是將HTML文件輸出為HTML標記,並使用狀態來表示。每個狀態收來自輸入資訊流的一個或多個位元組,並根據這些位元組更新下一個狀態。

該演算法相當複雜,於是我們基於一個簡單的例子來理解其原理:

<html>    
    <body>        
     Hello world    
    </body>
</html>複製程式碼
     初始狀態是資料狀態。在<html>中, 當解析遇到字元 < 時,狀態更改為“標記開啟狀態”,接受一個a-z字元會建立“起始標記”。
     這個狀態一直會保持到接收 > 字元。在此期間接收的每個字元都會附加到新的標記名稱上。
      遇到 > 標記之後,會傳送當前的標記,狀態改為“資料狀態”。<body> 標記也會是相同的處理。
      目前 html與body 標記均已發出,現在我們回到了資料狀態,當接收 Hello world 中的H字元時,將建立併傳送字元標記,此後每一個字元都會傳送一個字元標記。直到遇到</body>的 < 字元為止。
      </body> 中 解析到< 時,狀態回到了“標記開啟狀態”,接收的是/字元時,會建立 end tag token 並改為“標記名稱狀態”。這個狀態將會繼續保持,直到遇到 > 字元時結束。 

      </html> 也會進行同樣的處理。


HTML的樹構建演算法:
     在建立解析器的同時,也會建立 Document 物件。在構建樹階段,以 Document 為根節點DOM樹會不斷的修改,向其中新增各種元素。
      利用標記生成器( 標記化演算法 )傳送的每個節點的DOM 樹,會不斷進行處理。規範( W3C標準 )中定義了每個標記所對應的DOM元素,這些元素會在接受到相應的標記時建立。
      這些元素不僅會新增到DOM 樹中,還會新增到開放元素的堆疊中。此堆疊用於糾正巢狀錯誤和處理未關閉的標記。
       其演算法也可以用狀態機來描述,這些狀態為“插入模式”,
例子:

<html>    
    <body>        
    Hello world    
    </body>
</html>複製程式碼
此HTML構建樹流程:

瀏覽器渲染過程與原理淺析(一)

解析結束後的操作:
     此階段,瀏覽器會將文件標註為互動狀態,並開始解析那些處於延遲模式的指令碼(如: <script defer="defer" >),也就是那些應在文件解析完成後才執行的指令碼。然後,文件狀態將設定為“完成”,一個“載入”事件將隨之觸發。


瀏覽器的容錯機制:
     你在瀏覽 HTML 網頁時從來不會看到“語法無效”的錯誤。這是因為瀏覽器會糾正任何無效內容,然後繼續工作。
     不同瀏覽器的錯誤處理機制是相當一致的,但這種機制卻不是 HTML 當前規範的一部分。
需要注意,除非想作為反面教材出現容錯程式碼段,否則還請編寫格式正確的 HTML 程式碼。

瀏覽器渲染過程與原理淺析(二)我們會詳細說一下神祕的CSS解析器與解析器的原理,細緻的探討樣式與DOM 的關係。


相關文章