JavaScript 經常是視覺變更的觸發條件。有時會直接透過樣式操作進行變更,有時則會透過計算產生視覺變更,例如搜尋或排序資料。不當的時間安排或長時間執行的 JavaScript 是常見的效能問題原因,因此您應盡可能減少其影響。
樣式計算
透過新增及移除元素、變更屬性、類別或播放動畫等方式變更 DOM 時,瀏覽器會重新計算元素樣式,在多數情況下,部分或所有網頁的版面配置也會重新計算。這項程序稱為「樣式計算」。
瀏覽器會建立一組相符的選取器,藉此判斷哪些類別、偽元素選取器和 ID 會套用至任何指定元素,進而開始計算樣式。接著,處理相符的選取器中的樣式規則,並找出元素的最終樣式。
樣式重新計算在互動延遲中扮演的角色
Interaction to Next Paint (INP) 是一種以使用者為中心的執行階段效能指標,用於評估網頁對使用者輸入內容的整體回應速度。它會從使用者與網頁互動開始,到瀏覽器顯示下一個影格 (顯示使用者介面對應的視覺更新) 為止,測量互動延遲時間。
互動的一大要素是繪製下一個影格所需的時間。呈現下一個影格所需的轉譯作業由許多部分組成,包括在版面配置、繪製和合成作業前發生的頁面樣式計算作業。本指南著重於樣式計算費用,但減少任何互動的轉譯總時間長度也可以減少總延遲時間。
降低選取器的複雜度
簡化 CSS 選取器有助於加快網頁樣式計算速度。最簡單的選取器只會使用類別名稱,參照 CSS 中的元素:
.title {
/* styles */
}
但是,隨著任何專案規模擴增,這可能需要更複雜的 CSS,而且可能會建立的選取器如下:
.box:nth-last-child(-n+1) .title {
/* styles */
}
如要判斷這些樣式如何套用到網頁,瀏覽器必須有效詢問「是否含有 title
類別的元素,其父項是 box
類別的父項嗎?」這是父項元素的減號 (-nth-plus-1) 子項?瀏覽器可能需要一些時間才能完成這項作業。為簡化這項作業,您可以將選取器變更為更具體的類別名稱:
.final-box-title {
/* styles */
}
這些替換類別名稱看起來可能很奇怪,但可讓瀏覽器的工作變得簡單許多。舉例來說,在先前的版本中,瀏覽器必須先瞭解所有其他元素的所有資訊,才能判斷後續的元素是否可能是 nth-last-child
。比起僅根據類別名稱單獨將選取器與元素進行比對,這麼做的運算成本可能高出許多。
減少設定樣式的元素數量
另一個效能考量 (通常比選取器複雜度更重要) 是元素變更時需要執行的工作量。
一般來說,計算運算元素樣式的最壞情況成本,就是元素數量乘上選取器計數,因為瀏覽器需要至少檢查每個元素與每個樣式的比對結果一次,以便判斷是否相符。
樣式計算可直接指定少數元素,而非讓整個網頁失效。在新式瀏覽器中,這個問題通常較不嚴重,因為瀏覽器不一定需要檢查變更可能影響的所有元素。但較舊的瀏覽器不一定能妥善執行這類工作。請盡可能減少無效元素的數量。
評估樣式重新計算成本
您可以透過幾種方式評估瀏覽器中樣式重新計算的成本。每個步驟都會取決於您是否要在開發環境的瀏覽器中評估作業,或是評估此程序對實際網站使用者執行的時間。
在 Chrome 開發人員工具中評估樣式重新計算成本
您可以使用 Chrome 開發人員工具中的效能面板,評估樣式重新計算的成本。如要開始使用,請按照下列步驟操作:
- 開啟開發人員工具。
- 前往「成效」分頁。
- 勾選「選取器統計資料」核取方塊 (選用)。
- 按一下「錄製」。
- 與網頁互動。
停止錄影後,畫面會顯示類似下圖的畫面:
頂端的長條是縮小的火焰圖,也會繪製每秒影格數。活動越靠近條紋,瀏覽器繪製的速度就越快。如果您看到火焰圖表在頂端趨於平穩,且上方有紅色長條,表示您有工作會導致長時間執行的框架。
在捲動等互動期間,長時間執行的框架值得仔細研究。如果您看到大型紫色方塊,請放大活動並選取任何標示為「Recalculate Style」的工作,進一步瞭解可能耗費大量資源的樣式重新計算工作。
只要按一下事件,即可顯示其呼叫堆疊。如果轉譯工作是因使用者互動而產生,它會呼叫觸發樣式變更的 JavaScript。也會顯示變更所影響的元素數量 (在本例中是超過 900 個元素),以及樣式計算所花費的時間。您可以利用這些資訊,開始嘗試在程式碼中找出修正方法。
如果您在執行追蹤記錄之前勾選了「Performance」(效能面板) 設定中的「Selectorstats」(選取器統計資料) 核取方塊,追蹤記錄底部就會有另一個同名的分頁。
這個面板會提供每個選取器的相對成本相關資料,讓您找出耗用資源較多的 CSS 選取器。
詳情請參閱 CSS 選取器統計資料說明文件。
評估實際使用者樣式重新計算成本
如果您想知道網站實際使用者需要多久才能重新計算樣式,Long Animation Frames API 可提供必要的工具。這個 API 的資料已加入 web-vitals
JavaScript 程式庫,包括樣式重新計算時間。
如果您懷疑互動呈現延遲是網頁 INP 的主要影響因素,請找出重新計算網頁樣式的時間所需時間。詳情請參閱如何在欄位中評估樣式重新計算時間。