Critical Rendering Path (CRP)

定義

瀏覽器從取得 HTML 檔案到第一次呈現頁面內容的過程。

CRP 流程

  1. 下載 HTML 檔案
  2. 產生 DOM(解析 HTML)
  3. 下載 CSS 檔案
  4. 產生 CSSOM
  5. 執行 JS (如果有的話)
  6. 合併 DOM 和 CSSOM 為 Render Tree
  7. Layout
  8. Paint

產生 DOM 的流程

Bytes

取得的 HTML 檔案格式一開始為位元組

Characters

將位元組還原成字元。

Tokens

利用各個元素的開始與結束標籤確認各元素的階層,並將各元素解析為獨立的 tokens 。

Lexing(Tokens to Nodes)

將 token 所記錄的上下文關係與屬性解析為代表各元素的物件。

DOM

將物件以樹狀資料結構的方式儲存,成為 DOM 。

產生 CSSOM 的流程

和產生 DOM 的流程很像:
Characters -> Tokens -> Nodes -> CSSOM

差別:

  1. 所有可視的 Nodes 都在 body Node 之下
  2. 每個 child node 會被賦予 parent node 的 style 屬性(Cascade down)
  3. CSSOM 由於 cascade 特性,不能被分段解析,瀏覽器會把文件中所有的 CSS 都解析完畢,成為完整的 CSSOM 後,才會進行 render ,此為 Render Blocking 特性
  4. 越 specific 的樣式會越耗效能

產生 Render Tree

Render Tree 只會解析看得到的元素,遇到看不到的元素,表示不需要 render ,該 node 與其 children 會直接被忽略。

註: visibility: hidden 會影響 layout ,還是算 Render Tree 的範疇。

後續會從最上層 DOM 開始,將 style 和 DOM 合併後依序整合下來,形成 Render Tree 。

Layout (Reflow)

這步驟會計算 Render Tree 內所有元素在 viewport 內最終的位置,並從 <body> 開始依序往下定位。

只要是佈局會被影響的情況,瀏覽器在呈現畫面前必定會重算一次 Layout 。例如:

  • 轉手機方向
  • Resize
  • 增減、縮放、改變 DOM 尺寸

Paint (Rasterize)

在確定各元素的位置後,這步將資訊轉變為 pixels 呈現在頁面上。原則上越複雜的結構、顯色方式會讓 Paint 的過程越久。

小結

效能優化的原理就是盡量減少 CRP 各步驟所花費的時間,或盡量讓某些任務在重疊時間進行。

Reference

Google Web Dev - CRP