發布日期:2014 年 3 月 31 日
CSSOM 和 DOM 樹狀結構會合併為轉譯樹狀結構,然後用於計算每個可見元素的版面配置,並做為轉譯過程的輸入內容,將像素轉譯至螢幕。如要達到最佳算繪效能,請務必對每個步驟進行最佳化調整。
在上一節中,我們根據 HTML 和 CSS 輸入內容,建立 DOM 和 CSSOM 樹狀結構。不過,這兩者都是獨立的物件,可擷取文件的不同層面:一個描述內容,另一個則描述需要套用至文件的樣式規則。如何合併這兩者,讓瀏覽器在螢幕上算繪像素?
摘要
- DOM 和 CSSOM 樹狀結構會結合成轉譯樹狀結構。
- 轉譯樹狀圖只包含轉譯網頁所需的節點。
- 版面配置會計算每個物件的確切位置和大小。
- 最後一個步驟是繪製,會接收最終轉譯樹狀結構,並將像素轉譯至螢幕。
首先,瀏覽器會將 DOM 和 CSSOM 合併為「轉譯樹狀結構」,擷取網頁上所有可見的 DOM 內容,以及每個節點的所有 CSSOM 樣式資訊。
瀏覽器大致會執行下列步驟,建構轉譯樹狀結構:
從 DOM 樹狀結構的根層級開始掃遍每個可見節點。
- 部分節點不會顯示 (例如指令碼標記、元標記等),因為這些節點不會反映在轉譯的輸出內容中,因此會省略。
- 有些節點會使用 CSS 隱藏,也會從轉譯樹狀結構中省略;舉例來說,上例中的 span 節點會從轉譯樹狀結構中省略,因為我們有明確的規則,會在該節點上設定「display: none」屬性。
針對每個可見節點,找出並套用適當的 CSSOM 規則。
以內容和其計算樣式,發出可見的節點。
最終輸出內容是轉譯樹狀結構,其中包含螢幕上所有可見內容的內容和樣式資訊。有了轉譯樹狀結構,我們就可以繼續進行「版面配置」階段。
到目前為止,我們已計算出應顯示哪些節點,以及這些節點的計算樣式,但尚未計算出這些節點在裝置檢視區中的確切位置和大小,這就是「版面配置」階段,也稱為「重新流動」。
為確定網頁上每個物件的確切大小和位置,瀏覽器會從轉譯樹狀結構的根目錄開始掃遍。以這段程式碼為例:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Critial Path: Hello world!</title>
</head>
<body>
<div style="width: 50%">
<div style="width: 50%">Hello world!</div>
</div>
</body>
</html>
前述範例的 <body>
包含兩個巢狀 <div>
:第一個 (父項) <div>
將節點的顯示大小設為可視區域寬度的 50%
,而第二個 <div>
(包含在父項中) 將其 width
設為父項的 50%
,也就是可視區域寬度的 25%。
版面配置程序的輸出內容是「盒模型」,可精確擷取可視區域中每個元素的確切位置和大小:所有相對測量值都會轉換為螢幕上的絕對像素。
最後,我們知道哪些節點可見,以及這些節點的運算樣式和幾何圖形,因此可以將這些資訊傳遞至最終階段,將轉譯樹狀結構中的每個節點轉換為螢幕上的實際像素。這個步驟通常稱為「繪圖」或「光柵化」。
由於瀏覽器必須執行大量工作,這項作業可能需要一段時間。不過,Chrome 開發人員工具可以深入分析上述三個階段。請查看原始「Hello World」範例的版面配置階段:
- 「Layout」事件會擷取時間軸中的算繪樹狀結構建構、位置和大小計算作業。
- 版面配置完成後,瀏覽器會發出「小畫設定」和「小畫」事件,將轉譯樹狀結構轉換為螢幕上的像素。
執行轉譯樹狀結構建構、版面配置和繪製作業所需的時間,會因文件大小、套用的樣式和執行的裝置而異:文件越大,瀏覽器的工作量就越大;樣式越複雜,繪製作業所需的時間就越長 (例如,繪製單色會比較「便宜」,而計算和轉譯陰影則會比較「昂貴」)。
網頁最後會顯示在可視區域中:
以下是瀏覽器的快速步驟回顧:
- 處理 HTML 標記並建構 DOM 樹狀結構。
- 處理 CSS 標記並建構 CSSOM 樹狀結構。
- 將 DOM 和 CSSOM 合併為轉譯樹狀結構。
- 在轉譯樹狀結構上執行版面配置,以便計算每個節點的幾何圖形。
- 將個別節點繪製到畫面上。
雖然示範頁面看起來很簡單,但瀏覽器需要進行大量工作。如果 DOM 或 CSSOM 遭到修改,您必須重複執行這項程序,才能找出需要在螢幕上重新算繪的像素。
最佳化重要算繪路徑是指盡可能縮短執行上述步驟 1 至 5 所需的總時間。這樣一來,就能盡快在畫面上算繪內容,還能減少初始顯示後畫面更新之間經過的時間,也就是說,提高互動式內容的刷新率。