基石-初見瀏覽器(一):瀏覽器渲染

Su_py發表於2019-12-08

瀏覽器渲染原理

學習瀏覽器渲染原理是為了能夠提高頁面效能,避免無意間對效能造成損耗。並且面試過程中答得比較好的話... 雖然我還是一名在校生...

本文討論的是基於WebKit核心(Chrome和Safair)渲染引擎的內容,渲染引擎在不同核心實現的瀏覽器中存在差異。

概述

從服務端接受到資料後,瀏覽器將這些位元組碼轉變成渲染的畫素這一過程,都經歷了什麼?瞭解其中的過程,有助於我們寫出更加精幹的程式碼,這些過程簡稱為關鍵選渲染路徑。通過優化關鍵渲染路徑,能夠為構建高效能互動式操作打下基礎。 瀏覽器進行渲染頁面前,需要先構建出DOM樹和CSSOM樹,因此我們需要確保儘快將HTML程式碼和CSS程式碼提供給瀏覽器。

  • HTML 標記轉換成文件物件模型 (DOM),CSS 標記轉換成 CSS 物件模型 (CSSOM)
  • DOM 和 CSSOM 是獨立的資料結構

HTML檔案轉化成DOM樹

基石-初見瀏覽器(一):瀏覽器渲染

  1. 開啟網頁,瀏覽器首先通過網路請求對應的HTML檔案,由於計算機硬體是不識別字串的(HTML、CSS和JS 檔案),所以在網路傳輸過程中轉化成0和1的位元組資料。當瀏覽器接受收到這些位元組資料後,它會將位元組資料轉化成字串(characters)。

  2. 瀏覽器將轉換成的字串,按照W3C的標準規定轉化成各種token(令牌),例如<html>標籤等其他尖括號內的字串,每個token都具有特殊含義以及一組規則。

基石-初見瀏覽器(一):瀏覽器渲染

  1. 當結束標記化後,這些token會立即轉化為Node,同時這些Node會根據不同Node之間的關係構成一顆DOM樹。整個流程的最終輸出是我們訪問頁面的文件物件模型 (DOM),瀏覽器對頁面進行的進一步處理都會用到它。

    基石-初見瀏覽器(一):瀏覽器渲染

    補充:在node轉化為DOM樹這一過程中,是根據每個token之間的層級巢狀關係,進而確定DOM的樹形結構。並且DOM樹的構建是逐步逐步構建的,而不是在整個過程最後構建。 以上就是瀏覽器從網路中接收到HTML檔案後一系列的轉換過程。

在解析HTML檔案構建DOM樹時,還會遇到CSS和JS檔案,這時候瀏覽器也會去下載並解析這些檔案。但請記住在這過程中如果執行了JS程式碼,會暫停DOM樹的構建,目的是保證能夠正確的構建DOM樹(JavaScript程式碼能夠修改DOM節點)

CSS檔案轉換成CSSOM樹

在瀏覽器構建DOM樹時,在文件的head部分會遇到link標記,該標記引用一個外部CSS樣式表,由於預測到需要利用該檔案來進行渲染頁面,他會立即發出對該資源的請求。 與處理HTML時一樣,我們需要將收到的CSS檔案轉換成某種瀏覽器能夠理解和處理的東西。因此我們會重複建立DOM樹的過程來建立CSSOM樹。最終形成一顆CSSOM樹結構。

基石-初見瀏覽器(一):瀏覽器渲染

這一過程中,瀏覽器會確定每一個節點的樣式,此過程實際是比較消耗資源的。因為在設定樣式的時候可以直接設定樣式,也可以通過繼承獲得,所以瀏覽器就得遞迴CSSOM樹。最終確定某元素的樣式。 舉例:

    <div>
      <a> <span></span> </a>
    </div>
    <style>
      span {
        color: red;
      }
      div > a > span {
        color: red;
      }
    </style>
複製程式碼

對於第一種情況,瀏覽器需要找到頁面中所有的span標籤然後設定顏色。 對於第二種情況,瀏覽器首先需要找到所有的span標籤,然後找到span標籤上的a標籤,最後找到div標籤,確定滿足條件的span元素後設定顏色,這樣的遞迴過程很複雜。 所以要避免寫過於具體的CSS選擇器,對於HTML來說盡量少新增無意義的標籤,保持層級扁平化。

生成RenderTree(渲染樹)

CSSOM樹和DOM樹合併成渲染樹。但它們都是獨立的物件,分別用於網羅文件不同方面的資訊:一個描述內容,另一個則是描述需要對文件應用的樣式規則。

基石-初見瀏覽器(一):瀏覽器渲染

可是我們應該如何合併兩顆樹呢?並讓瀏覽器螢幕上渲染畫素呢?

為構建渲染樹,瀏覽器大體上完成以下工作

1.從DOM樹的根節點開始遍歷每個可見的節點

  • 某些節點不可見(例如指令碼標記 元標記等)導致他們並不會體現在渲染輸出中,所以會忽略
  • 某些節點通過CSS隱藏,因此在渲染樹中會被忽略,例如display:none

2.對於每個可見的節點為他們找到匹配的CSSOM規則並應用他們。 最終輸出的渲染樹包含了螢幕上的所有可見內容及其樣式資訊。有了渲染樹,我們就可以進入“佈局”階段。

佈局(layout)

到目前為止,我們已經確定了哪些節點是可見的,以及經過計算後的樣式資訊,但是我們並沒有計算他們在裝置視口中的準確位置和大小。這就是在佈局階段需要解決的,同時也稱為自動重排 當瀏覽器經過佈局計算後,確定了每個元素的大小以及精確的位置,並將所有測量值都轉換為螢幕上的絕對畫素後,將會把這些資訊傳遞給最後一個階段,繪製階段

小結

上述步驟都需要瀏覽器完成大量工作,所以相當耗時。執行渲染樹構建、佈局和繪製所需的時間將取決於文件大小、應用的樣式,以及執行文件的裝置:文件越大,瀏覽器需要完成的工作就越多;樣式越複雜,繪製需要的時間就越長。 我們說起來可能很簡單,實際上瀏覽器卻需要完成相當多的工作。如果 DOM樹 或 CSSOM樹 被修改,只能再執行一遍以上所有步驟,以確定哪些畫素需要在螢幕上進行重新渲染。

概述一下瀏覽器所經歷的過程:

  1. 處理 HTML 標記並構建 DOM 樹。
  2. 處理 CSS 標記並構建 CSSOM 樹。
  3. 將 DOM 與 CSSOM 合併成一個渲染樹。
  4. 根據渲染樹來佈局,以計算每個節點的幾何資訊。
  5. 將各個節點繪製到螢幕上。

謝謝各位看官,記得點贊。下一篇文章會再續前緣,瀏覽器是如何收到各種檔案的?

經典問題的分析:輸入一個url後都發生了什麼?

基石-初見瀏覽器(一):瀏覽器渲染

相關文章