實際上,DOM 大小對互動性影響的程度可能比您想像的更大。本指南將說明原因,並提供相關因應措施。
宇宙不幸,:當您建立網頁時,該網頁就會包含文件物件模型 (DOM)。DOM 代表網頁 HTML 的結構,可讓 JavaScript 和 CSS 存取網頁的結構和內容。
但問題是,DOM 的「大小」會影響瀏覽器快速且有效率的頁面算繪能力。一般來說,DOM 越大,一開始轉譯網頁的時間就越貴,之後在頁面生命週期中更新其轉譯方式時,就會花費較多成本。
在 DOM 非常大的網頁中,如果修改或更新 DOM 的互動會觸發耗時的版面配置工作,進而影響網頁快速回應的能力,就會造成問題。耗時的版面配置作業可能會影響網頁的與下一個顯示的內容互動;如果您希望網頁能快速回應使用者互動,請務必確保 DOM 大小僅為必要的大小。
網頁的 DOM 為何「太」大?
Lighthouse 指出,網頁的 DOM 大小超過 1,400 個節點時,大小過大。如果網頁的 DOM 超過 800 個節點,Lighthouse 就會開始發出警告。以下列 HTML 為例:
<ul>
<li>List item one.</li>
<li>List item two.</li>
<li>List item three.</li>
</ul>
在上述程式碼中,有四個 DOM 元素:<ul>
元素及其三個 <li>
子元素。網頁的節點數肯定會比這個數字多得多,因此請務必瞭解如何控制 DOM 大小,以及在網頁的 DOM 縮減到最小值後,如何透過其他策略最佳化轉譯作業。
大型 DOM 對網頁效能有何影響?
大型 DOM 會對網頁效能造成以下影響:
- 在網頁初始轉譯期間。將 CSS 套用至網頁時,系統會建立類似 DOM 的結構,稱為 CSS 物件模型 (CSSOM)。隨著 CSS 選取器的特定性增加,CSSOM 會變得更複雜,需要花費更多時間執行必要的版面配置、樣式、合成和繪製作業,才能將網頁繪製到畫面上。這項額外工作會增加在網頁載入初期發生的互動延遲時間。
- 當互動透過元素插入或刪除方式修改 DOM,或是修改 DOM 內容和樣式時,轉譯該更新所需的工作可能會導致版面配置、樣式、撰寫和繪製工作會耗用大量資源。就像網頁的初始算繪作業一樣,當 HTML 元素因互動而插入 DOM 時,CSS 選取器的特定性增加可能會增加算繪作業。
- JavaScript 查詢 DOM 時,DOM 元素的參照會儲存在記憶體中。舉例來說,如果您呼叫
document.querySelectorAll
來選取頁面上所有的<div>
元素,如果結果傳回大量 DOM 元素,就可能會消耗記憶體費用。
以上所有這些因素都會影響互動性,但上方清單中第二個項目有特定的重要性。如果互動導致 DOM 改變,就會啟動許多可能導致網頁上的 INP 不佳的工作。
如何測量 DOM 大小?
您可以透過幾種方式測量 DOM 大小。第一個方法是使用 Lighthouse。執行稽核時,「診斷」標題下的「避免 DOM 大小過大」稽核會顯示目前網頁所含 DOM 的統計資料。在這個部分,您可以查看 DOM 元素的總數、含有最多子元素的 DOM 元素,以及最深層的 DOM 元素。
更簡單的方法是在任何主要瀏覽器中,使用開發人員工具中的 JavaScript 控制台。如要取得 DOM 中的 HTML 元素總數,您可以在頁面載入後,在控制台中使用下列程式碼:
document.querySelectorAll('*').length;
如要即時查看 DOM 大小更新,也可以使用效能監控工具。您可以使用這項工具,將版面配置和樣式操作 (以及其他效能層面) 與目前的 DOM 大小建立關聯。
如果 DOM 大小接近 Lighthouse DOM 大小的警告門檻 (或完全失敗),下一個步驟就是瞭解如何縮減 DOM 大小,以改善網頁回應使用者互動的能力,進而提升網站的 INP。
如何評估互動影響的 DOM 元素數量?
如果您在實驗室中分析互動速度緩慢的情況,且懷疑這可能與網頁 DOM 大小有關,您可以選取「Recalculate Style」(重新計算樣式) 標籤的任何活動,並觀察底部面板中的內容相關資料,藉此瞭解有多少 DOM 元素受到影響。
請注意,在上述螢幕截圖中,選取作品的樣式重新計算功能後,畫面會顯示受影響的元素數量。以上螢幕截圖顯示 DOM 大小在內含多個 DOM 元素的網頁轉譯作業中, DOM 大小影響極大情況,但這項診斷資訊就十分實用,有助於判斷 DOM 大小是否為回應互動後,下一個影格繪製所需的時間長度限制。
如何縮減 DOM 大小?
除了檢查網站 HTML 是否有不必要的標記,減少 DOM 深度是縮減 DOM 大小的主要方法。如果您在瀏覽器開發人員工具的「Elements」分頁中看到類似以下的標記,就表示 DOM 可能過於深層:
<div>
<div>
<div>
<div>
<!-- Contents -->
</div>
</div>
</div>
</div>
看到這類模式時,您可以壓平 DOM 結構來簡化這些模式。這樣可以減少 DOM 元素數量,讓您有機會簡化網頁樣式。
DOM 深度也可能是您使用的架構的症狀。特別是,以元件為基礎的架構 (例如依賴 JSX 的架構) 需要您在父項容器中巢狀放置多個元件。
不過,許多架構都允許您使用片段,避免巢狀元件。提供片段做為功能的元件式架構包括但不限於:
在您選擇的架構中使用片段,可降低 DOM 深度。如果您擔心整併 DOM 結構對樣式的影響,使用更現代化 (且速度更快) 的版面配置模式 (例如 flexbox 或 Grid) 可能會有幫助。
其他建議策略
即使您對於簡化 DOM 樹狀結構及移除不必要的 HTML 元素來盡量縮小 DOM 而感到不堪負荷,但隨著使用者互動行為改變,這個模型可能還是相當龐大,並造成大量轉譯工作。假如您在這個職位,可考慮限制顯示網頁的功能。
考慮採用加法式方法
某個位置,很有可能在網頁一開始轉譯時,使用者無法看見網頁內容。此時您可以省略 DOM 的部分,從而延遲載入 HTML,但當使用者與網頁初始隱藏元素互動時,就加入這些部分。
此方法在初始載入期間或之後可能都非常實用。對於初始網頁載入作業,您會事先執行較少的轉譯工作,也就是說,初始 HTML 酬載會變得較輕,且轉譯速度會加快。如此一來,這個重要期間的互動就能增加更多互動機會,並降低主執行緒注意力的競爭程度。
如果網頁中有許多部分最初在載入時隱藏,系統也可能會加快其他觸發重新轉譯工作的互動速度。不過,隨著其他互動在 DOM 加入更多互動,隨著 DOM 在整個網頁生命週期中持續成長,算繪作業也會增加。
隨著時間的推移而加入 DOM 可能很困難,而且有自己的取捨。如果您採用這種做法,很可能會發出網路要求,以便取得資料,並在使用者互動時,將您想加入網頁的 HTML 填入。雖然傳輸中的網路要求不會計入 INP,但可能會增加感知延遲時間。如果可以,請顯示載入旋轉圖示或其他指標,說明系統正在擷取資料,以便使用者瞭解發生的情況。
限制 CSS 選取器複雜度
瀏覽器剖析 CSS 中的選取器時,必須掃遍 DOM 樹狀結構,瞭解這些選取器如何套用至目前的版面配置,以及是否適用這些選取器。這些選取器越複雜,瀏覽器為了執行網頁的初始轉譯作業,所需的工作量就越多,而且如果網頁因互動而改變,樣式重新計算和版面配置也就更多了。
使用 content-visibility
屬性
CSS 提供 content-visibility
屬性,可有效延遲轉譯畫面外 DOM 元素。元素接近可視區域時,就會依需求顯示。content-visibility
的優點不僅僅會減少初次轉譯頁面時的大量轉譯工作量,也讓網頁 DOM 因使用者互動而改變時,會略過螢幕外元素的轉譯作業。
結論
將 DOM 大小縮減至必要的程度,是改善網站 INP 的好方法。這樣一來,您就能縮短瀏覽器在 DOM 更新時執行版面配置和轉譯作業所需的時間。即使無法有效縮減 DOM 大小,仍有些技術能將轉譯工作隔離到 DOM 子樹狀結構 (例如 CSS 壓制和 content-visibility
CSS 屬性) 中。
無論如何,請創造能減少轉譯工作的環境,並減少網頁因應互動情形的轉譯工作量,結果會提升使用者與網站互動時的反應。也就是說,網站的 INP 會較低,進而改善使用者體驗。