瀏覽器渲染 pipeline Part 2(聚焦於渲染引擎)

在解析 HTML 和 CSS 之後,接下來會發生什麼?

December 3, 2024

回顧前一部分

在文章瀏覽器渲染 pipeline 第一部分中,我們已經回顧了瀏覽器渲染 pipeline part 1,並了解到瀏覽器會解析 HTML 和 CSS 並建立 DOM 樹和 CSSOM 樹,這背後的主要角色是渲染引擎。

不同類型的渲染引擎

不同的瀏覽器使用不同的渲染引擎,以下是一些例子:

主要流程

在從網路層獲取請求文件的內容後,渲染引擎的基本流程如下:

解析階段

在這個階段,渲染引擎會解析 HTML 和 CSS,並建立 DOM 樹和 CSSOM 樹。 同時,JavaScript 引擎會執行指令碼,每個指令碼都會在單一執行緒中執行,並一個接一個地推入呼叫堆疊,執行順序基於 LIFO(後進先出)。如果觸發了 DOM 事件或計時器事件,它會被推入事件佇列。請記住,呼叫堆疊上的執行優先順序始終高於事件佇列,您可以參考 JavaScript 事件循環獲取更多詳細資訊。

渲染階段

在這個階段,DOM 樹和 CSSOM 樹會組合成渲染樹,然後瀏覽器會進行渲染樹的佈局和繪製,最後合成最終圖像並顯示在螢幕上。讓我們深入了解每個階段。

佈局樹

在這個階段,瀏覽器會做幾件事:

  1. 計算每個節點的位置和大小。
  2. 處理盒模型、定位和浮動。
  3. 然後建立佈局樹。

繪製階段

在這個階段,瀏覽器會:

  1. 將佈局轉換為實際像素。
  2. 處理繪製順序,例如 z-index。
  3. 處理顏色、邊框或陰影等。
  4. 在螢幕上繪製內容。

合成階段

在這個階段,瀏覽器會將不同的圖層合成為單一圖像,並顯示在螢幕上。

回流和重繪

某些操作會觸發回流或重繪,讓我們回顧一下:

回流

回流是重新計算元素佈局的過程,當元素的大小或位置改變時會觸發,例如我們新增元素、更改元素樣式或調整視窗大小等。這是一種非常耗費資源的操作,我們應該盡可能避免。

element.style.width = "100px";
element.style.height = "100px";
element.style.left = "100px";

上述程式碼展示了一個簡單的回流,因為我們多次更改元素的樣式。更好的做法是使用 element.cssText 來一次性更改元素的樣式,像這樣:

// Batches changes
element.cssText = "width: 100px; height: 100px; left: 100px;";

🧐 嗯...RWD(響應式網頁設計)會觸發回流嗎?

響應式設計

初始載入時的媒體查詢會靜態套用樣式,所以它們不會導致額外的回流,但當視窗大小調整時,瀏覽器需要重新計算元素的佈局,所以會觸發回流。讓我們看一個例子:

<style>
  @media (min-width: 768px) {
      .container {
          width: 750px;
      }
  }
  @media (min-width: 1200px) {
      .container {
          width: 1170px;
  }
</style>

請記住,如果 CSS 值更改了佈局,例如 width、height、left、top、margin、padding 等,會觸發回流;如果只更改了視覺屬性,例如 color、border、shadow 等,會觸發重繪。

重繪

當只有視覺屬性改變時觸發,例如顏色、邊框或陰影等,這需要重新執行繪製和合成階段,比回流消耗更少的資源。

結論

  1. 在網路層,瀏覽器會獲取請求文件的內容。
  2. 在解析階段,瀏覽器會解析 HTML 和 CSS,並建立 DOM 樹和 CSSOM 樹。
  3. 在渲染階段,瀏覽器會對渲染樹進行佈局和繪製,最後合成最終圖像並顯示在螢幕上。
  4. 某些操作會觸發回流或重繪,我們應該盡可能避免它們。
  5. 影響佈局的 CSS 值更改會觸發回流。
  6. 不影響佈局的 CSS 值更改會觸發重繪。
  7. 回流比重繪消耗更多資源。
回到部落格 🏃🏽‍♀️