關鍵渲染路徑

關鍵渲染路徑是瀏覽器將 HTML、CSS 和 JavaScript 轉換為螢幕上的畫素所經歷的一系列步驟。最佳化關鍵渲染路徑可以提高渲染效能。關鍵渲染路徑包括文件物件模型 (DOM)、CSS 物件模型 (CSSOM)、渲染樹和佈局。

在解析 HTML 時建立文件物件模型。HTML 可能會請求 JavaScript,而 JavaScript 又可能會更改 DOM。HTML 包含或發出對樣式的請求,這些樣式又會構建 CSS 物件模型。瀏覽器引擎將兩者結合起來建立渲染樹。佈局確定頁面上所有內容的大小和位置。確定佈局後,畫素就會繪製到螢幕上。

最佳化關鍵渲染路徑可以縮短首次渲染時間。瞭解和最佳化關鍵渲染路徑對於確保重排和重繪能夠以每秒 60 幀的速度發生、確保使用者互動的效能以及避免卡頓非常重要。

瞭解 CRP

Web 效能包括伺服器請求和響應、載入、指令碼、渲染、佈局以及將畫素繪製到螢幕上。

對網頁或應用程式的請求始於 HTTP 請求。伺服器傳送包含 HTML 的響應。然後瀏覽器開始解析 HTML,將接收到的位元組轉換為 DOM 樹。瀏覽器每次找到指向外部資源(無論是樣式表、指令碼還是嵌入的影像引用)的連結時,都會啟動請求。一些請求是阻塞的,這意味著在處理匯入的資源之前,其餘 HTML 的解析會暫停。瀏覽器繼續解析 HTML,發出請求並構建 DOM,直到到達末尾,此時它會構建 CSS 物件模型。在 DOM 和 CSSOM 完成後,瀏覽器構建渲染樹,計算所有可見內容的樣式。渲染樹構建完成後,就會發生布局,定義所有渲染樹元素的位置和大小。完成後,頁面就會渲染或“繪製”到螢幕上。

文件物件模型

DOM 構建是增量的。HTML 響應變為標記,標記變為節點,節點變為 DOM 樹。單個 DOM 節點以 startTag 標記開始,以 endTag 標記結束。節點包含有關 HTML 元素的所有相關資訊。資訊使用標記進行描述。節點根據標記層次結構連線到 DOM 樹中。如果另一組 startTag 和 endTag 標記出現在一組 startTag 和 endTag 標記之間,則表示一個節點在另一個節點內部,這就是我們定義 DOM 樹層次結構的方式。

節點數量越多,關鍵渲染路徑中的後續事件所需的時間就越長。進行測量!幾個額外的節點不會產生很大影響,但請記住,新增許多額外的節點會影響效能。

CSS 物件模型

DOM 包含頁面上的所有內容。CSSOM 包含有關如何設定 DOM 樣式的所有資訊。CSSOM 與 DOM 類似,但有所不同。雖然 DOM 構建是增量的,但 CSSOM 不是。CSS 是渲染阻塞的:瀏覽器會阻止頁面渲染,直到它接收並處理所有 CSS。CSS 是渲染阻塞的,因為規則可以被覆蓋,因此在 CSSOM 完成之前無法渲染內容。

CSS 有自己的一套規則來識別有效標記。請記住,CSS 中的 C 代表“層疊”。CSS 規則會層疊。當解析器將標記轉換為節點時,子節點將繼承父節點的一些樣式。增量處理功能不適用於 CSS,就像 HTML 那樣,因為後續規則可能會覆蓋先前的規則。CSS 物件模型在解析 CSS 時構建,但直到完全解析後才能用於構建渲染樹,因為要被後續解析覆蓋的樣式不應渲染到螢幕上。

在選擇器效能方面,不太具體的選擇器比更具體的選擇器更快。例如,.foo {}.bar .foo {} 快,因為當瀏覽器找到 .foo 時,在第二種情況下,它必須向上遍歷 DOM 以檢查 .foo 是否具有祖先 .bar。更具體的標籤需要瀏覽器做更多工作,但這項開銷可能不值得最佳化。

如果測量解析 CSS 所需的時間,您會驚歎於瀏覽器的速度。更具體的規則開銷更大,因為它必須遍歷 DOM 樹中的更多節點——但這種額外開銷通常很小。先測量。根據需要最佳化。特異性可能不是您最容易解決的問題。在 CSS 方面,選擇器效能最佳化改進只會以微秒為單位。還有其他最佳化 CSS 的方法,例如縮小和透過使用媒體查詢將延遲 CSS 分離到非阻塞請求中。

渲染樹

渲染樹同時捕獲內容和樣式:DOM 和 CSSOM 樹合併到渲染樹中。為了構建渲染樹,瀏覽器會檢查每個節點(從 DOM 樹的根節點開始),並確定哪些 CSS 規則附加到該節點。

渲染樹僅捕獲可見內容。head 部分(通常)不包含任何可見資訊,因此不包含在渲染樹中。如果元素上設定了 display: none;,則它及其任何後代都不會出現在渲染樹中。

佈局

構建渲染樹後,佈局就成為可能。佈局取決於螢幕大小。佈局步驟確定元素在頁面上的位置和顯示方式,確定每個元素的寬度和高度,以及它們彼此之間的關係。

元素的寬度是多少?根據定義,塊級元素的預設寬度為其父級寬度的 100%。寬度為 50% 的元素將是其父級寬度的一半。除非另有定義,否則 body 的寬度為 100%,這意味著它將是視口寬度的 100%。裝置的寬度會影響佈局。

視口元標記定義了佈局視口的寬度,從而影響佈局。如果沒有它,瀏覽器將使用預設的視口寬度,在預設全屏瀏覽器中通常為 960px。在預設全屏瀏覽器(如手機瀏覽器)中,透過設定 <meta name="viewport" content="width=device-width">,寬度將是裝置的寬度而不是預設視口寬度。當用戶在橫向和縱向模式之間旋轉手機時,device-width 會發生變化。每次旋轉裝置或調整瀏覽器大小都會發生布局。

DOM 會影響佈局效能——節點數量越多,佈局所需的時間就越長。如果在滾動或其他動畫期間需要佈局,它可能會成為瓶頸,導致卡頓。雖然載入或方向更改時 20 毫秒的延遲可能沒問題,但它會導致動畫或滾動時的卡頓。每當渲染樹被修改(例如,新增節點、更改內容或更新節點上的盒模型樣式)時,都會發生布局。

為了減少佈局事件的頻率和持續時間,請批次更新並避免對盒模型屬性進行動畫處理。

繪製

最後一步是將畫素繪製到螢幕上。建立渲染樹併發生布局後,就可以將畫素繪製到螢幕上。載入時,整個螢幕都會被繪製。之後,只會重新繪製螢幕上受影響的區域,因為瀏覽器經過最佳化,可以重新繪製所需的最小區域。繪製時間取決於應用於渲染樹的更新型別。雖然繪製過程非常快,因此可能不是提高效能時最值得關注的地方,但請務必記住,在測量動畫幀可能需要多長時間時,要考慮佈局和重新繪製時間。應用於每個節點的樣式會增加繪製時間,但刪除使繪製時間增加 0.001 毫秒的樣式可能不會為您帶來最大的最佳化收益。請務必先進行測量。然後,您可以確定它是否應成為最佳化的優先事項。

最佳化 CRP

透過優先考慮載入哪些資源、控制載入順序以及減小這些資源的檔案大小來提高頁面載入速度。效能技巧包括 1) 透過延遲非關鍵資源的下載、將其標記為非同步或完全消除它們來最大程度地減少關鍵資源的數量,2) 最佳化每個請求所需請求的數量以及每個請求的檔案大小,以及 3) 透過優先下載關鍵資產來最佳化關鍵資源的載入順序,從而縮短關鍵路徑長度。