對版面配置位移進行偵錯

瞭解如何找出並修正版面配置偏移問題。

發布日期:2021 年 3 月 11 日,上次更新日期:2025 年 2 月 7 日

本文第一部分將介紹用於偵錯版面配置偏移的工具,第二部分則會討論如何找出版面配置偏移的原因。

您可以使用版面配置不穩定 API 或 DevTools 等工具來偵錯版面配置變動,這些工具會以更容易消化的格式匯總此 API 的資料。

Layout Instability API 是用於評估及回報版面配置變動情形的瀏覽器機制。所有用於偵錯版面配置位移的工具 (包括 DevTools) 最終都是以 Layout Instability API 建構。不過,由於 Layout Instability API 具備彈性,因此直接使用這項 API 也是強大的偵錯工具。

用量

用於評估累計版面配置位移 (CLS) 的程式碼片段,也可以用於偵錯版面配置位移。以下程式碼片段會將版面配置變更記錄到控制台。檢查這個記錄可讓您瞭解版面配置偏移的時間、位置和方式。

let cls = 0;
new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    if (!entry.hadRecentInput) {
      cls += entry.value;
      console.log('Current CLS value:', cls, entry);
    }
  }
}).observe({type: 'layout-shift', buffered: true});

執行這個指令碼時,請注意:

  • buffered: true 選項表示 PerformanceObserver 應檢查瀏覽器的 成效項目緩衝區,找出在觀察器初始化前建立的成效項目。因此,PerformanceObserver 會回報在初始化前後發生的版面配置變更。檢查主控台記錄時請留意這一點。初始版面配置變更過多,可能反映出報告積壓,而非突然發生大量版面配置變更。
  • 為避免影響效能,PerformanceObserver 會等待主執行緒閒置,再回報版面配置變動。因此,視主執行緒的繁忙程度而定,在版面配置變更發生時和在控制台中記錄時之間,可能會有些微的延遲。
  • 這個指令碼會忽略使用者輸入後 500 毫秒內發生的版面配置移位,因此不會計入 CLS。

系統會使用兩個 API 組合回報版面配置偏移資訊:LayoutShiftLayoutShiftAttribution 介面。以下各節將詳細說明這些介面。

LayoutShift

系統會使用 LayoutShift 介面回報每個版面配置變動。項目的內容如下所示:

duration: 0
entryType: "layout-shift"
hadRecentInput: false
lastInputTime: 0
name: ""
sources: (3) [LayoutShiftAttribution, LayoutShiftAttribution, LayoutShiftAttribution]
startTime: 11317.934999999125
value: 0.17508567530168798

上一個項目表示版面配置移位,其中三個 DOM 元素變更了位置。這個特定版面配置位移的分數為 0.175

以下是 LayoutShift 例項的屬性,與版面配置位移的偵錯作業最相關:

屬性 說明
sources sources 屬性會列出在版面配置轉移期間移動的 DOM 元素。這個陣列最多可包含五個來源。如果有超過五個元素受到版面配置位移的影響,系統會回報五個最大的版面配置位移來源 (以對版面配置穩定性造成的影響來評估)。這項資訊會透過 LayoutShiftAttribution 介面回報 (詳情請見下文)。
value value 屬性會回報特定版面配置位移的版面配置位移分數
hadRecentInput hadRecentInput 屬性可指出版面配置是否在使用者輸入後的 500 毫秒內發生位移。
startTime startTime 屬性會指出版面配置移位發生的時間。startTime 以毫秒為單位,並以網頁載入開始時間為基準。
duration duration 屬性一律設為 0。這項屬性會繼承自 PerformanceEntry 介面 (LayoutShift 介面會擴充 PerformanceEntry 介面)。不過,時間長度概念不適用於版面配置偏移事件,因此會設為 0。如需 PerformanceEntry 介面的相關資訊,請參閱規格

LayoutShiftAttribution

LayoutShiftAttribution 介面會說明單一 DOM 元素的單一位移。如果版面配置移位期間有多個元素移位,sources 屬性就會包含多個項目。

舉例來說,以下 JSON 對應至一個來源的版面配置偏移:將 <div id='banner'> DOM 元素從 y: 76 向下偏移至 y:246

// ...
  "sources": [
    {
      "node": "div#banner",
      "previousRect": {
        "x": 311,
        "y": 76,
        "width": 4,
        "height": 18,
        "top": 76,
        "right": 315,
        "bottom": 94,
        "left": 311
      },
      "currentRect": {
        "x": 311,
        "y": 246,
        "width": 4,
        "height": 18,
        "top": 246,
        "right": 315,
        "bottom": 264,
        "left": 311
      }
    }
  ]

node 屬性會識別已移位的 HTML 元素。在開發人員工具中將滑鼠游標懸停在這個屬性上,即可醒目顯示對應的網頁元素。

previousRectcurrentRect 屬性會回報節點的大小和位置。

  • xy 座標分別回報元素左上角的 x 座標和 y 座標
  • widthheight 屬性分別回報元素的寬度和高度。
  • toprightbottomleft 屬性會回報與元素指定邊緣相對應的 x 或 y 座標值。換句話說,top 的值等於 ybottom 的值等於 y+height

如果 previousRect 的所有屬性都設為 0,表示元素已移至檢視區塊。如果 currentRect 的所有屬性都設為 0,表示元素已移出檢視範圍。

解讀這些輸出內容時,最重要的一點是,列為「sources」的元素,就是在版面配置變動期間移動的元素。不過,這些元素可能只間接與版面配置不穩定的「根本原因」相關。以下列舉幾個例子。

示例 1

這項版面配置變更會以一個來源回報:元素 B。不過,造成這項版面配置位移的根本原因是元素 A 的大小變更。

範例:顯示元素尺寸變更導致版面配置偏移

範例 2

在本例中,系統會以兩個來源 (元素 A 和元素 B) 回報版面配置變更。這個版面配置位移的根本原因是元素 A 的位置變更。

範例:顯示元素位置變更導致版面配置偏移

示例 3

本例中的版面配置偏移會以一個來源回報:元素 B。變更元素 B 的位置導致版面配置位移。

範例:顯示元素位置變更導致版面配置偏移

示例 4

雖然元素 B 會變更大小,但這個範例中並不會發生版面配置位移。

範例:顯示元素變更大小但未造成版面配置偏移

請參閱這部範例影片,瞭解 Layout Instability API 如何回報 DOM 變更。

開發人員工具

開發人員工具提供多種工具,可協助您偵錯版面配置變動。

效能面板

「效能」面板的即時指標檢視畫面可讓您與網頁互動,並監控 CLS 分數,找出造成版面配置大幅位移的互動。

Chrome 開發人員工具效能面板的即時指標畫面中顯示版面配置位移記錄。
在互動時,您可以透過「成效」面板的即時指標檢視畫面,監控網頁的 CLS 分數。

一旦您能夠可靠地重現版面配置偏移,就可以執行追蹤作業,取得更多詳細資料:

Chrome 開發人員工具效能面板中顯示的版面配置位移記錄。
在「Performance」面板中記錄新的追蹤記錄後,結果的「Layout Shifts」軌跡會填入紫色長條,顯示 Layout Shift 叢集。按一下鑽石圖示,即可在「摘要」面板中顯示變動動畫和詳細資料。

版面配置位移會在「Layout shifts」軌道中醒目顯示。紫色線條會將變化分組成班別叢集,其中的鑽石圖示代表該叢集中的個別班別。鑽石的大小與位移量成正比,方便您鎖定最大的位移。

點選班次後,畫面會彈出一個視窗,顯示班次的動畫,並以紫色標示轉移的元素。

此外,Layout Shift 記錄的「摘要」檢視畫面會顯示開始時間、轉換分數,以及轉換的元素。這對於進一步瞭解載入 CLS 問題的詳細資訊特別有用,因為這類問題很容易透過重新載入效能設定檔來複製。

這項資料也會連結至左側「洞察」面板中顯示的「版面配置位移原因」洞察資料,其中會在頂端顯示總 CLS,以及版面配置位移的可能原因。

如要進一步瞭解如何使用「Performance」面板,請參閱「成效分析參考資料」。

醒目顯示版面配置位移區域

醒目顯示版面配置位移區域,可讓您一目瞭然地掌握頁面上版面配置位移的位置和時間。

如要在開發人員工具中啟用版面配置位移區域,請依序前往「Settings」>「More Tools」>「Rendering」>「Layout Shift Regions」,然後重新整理要偵錯的頁面。版面配置位移區域會以紫色標示。

找出版面配置位移原因的思考過程

無論版面配置移位的時間或方式為何,您都可以按照下列步驟找出原因。您可以搭配執行 Lighthouse 來執行這些步驟,但請注意,Lighthouse 只能在初始網頁載入期間找出版面配置位移。此外,Lighthouse 也只能針對某些版面配置變更原因提供建議,例如沒有明確寬度和高度的圖片元素。

找出版面配置位移的原因

下列事件可能會導致版面配置偏移:

  • DOM 元素位置的變更
  • DOM 元素的尺寸變更
  • 插入或移除 DOM 元素
  • 觸發版面配置的動畫

具體來說,位於位移元素前方的 DOM 元素,最有可能是「造成」版面配置位移的元素。因此,在調查版面配置位移的原因時,請考慮以下事項:

  • 先前元素的位置或尺寸是否有變動?
  • 在移位的元素之前,是否有插入或移除 DOM 元素?
  • 是否明確變更了移位的元素位置?

如果前一個元素並未造成版面配置偏移,請繼續搜尋,並考量其他前一個元素和附近元素。

此外,版面配置偏移的方向和距離也可以提供有關根本原因的提示。舉例來說,向下移動的幅度越大,通常表示插入了 DOM 元素;而版面配置的移動幅度為 1 或 2 像素時,通常表示套用了相衝突的 CSS 樣式,或是載入及套用網頁字型。

圖表顯示字型交換造成的版面配置變動
在這個範例中,字型交換導致網頁元素向上移動五個像素。

以下是一些最常導致版面配置位移事件的特定行為:

元素位置的變更 (非因其他元素的移動而變更)

這類變更通常是因為:

  • 較晚載入的樣式表,或覆寫先前宣告的樣式。
  • 動畫和轉場效果。

元素的尺寸變更

這類變更通常是因為:

  • 較晚載入的樣式表,或覆寫先前宣告的樣式。
  • 圖片和 iframe 沒有 widthheight 屬性,且在「插槽」算繪後載入。
  • 不含 widthheight 屬性的文字區塊,會在文字算繪後交換字型。

插入或移除 DOM 元素

這通常是因為:

  • 插入廣告和其他第三方嵌入內容。
  • 插入橫幅、快訊和模式。
  • 無限捲動和其他 UX 模式,會在現有內容上方載入額外內容。

觸發版面配置的動畫

某些動畫效果可觸發版面配置。這類常見的例子是,DOM 元素透過遞增 topleft 等屬性而非使用 CSS 的 transform 屬性來產生動畫效果。詳情請參閱「如何建立高效能 CSS 動畫」。

重現版面配置位移

您無法修正無法重現的版面配置位移。如要進一步瞭解網站版面配置的穩定性,最簡單且最有效的方法之一,就是花 5 到 10 分鐘與網站互動,並以觸發版面配置變更為目標。執行這項操作時,請保持控制台開啟狀態,並使用 Layout Instability API 回報版面配置變動。

如要找出難以定位的版面配置偏移,建議您使用不同的裝置和連線速度重複執行這項練習。特別是,使用較慢的連線速度,有助於更輕鬆地找出版面配置位移。此外,您也可以使用 debugger 陳述式,更輕鬆地逐步執行版面配置變更。

new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    if (!entry.hadRecentInput) {
      cls += entry.value;
      debugger;
      console.log('Current CLS value:', cls, entry);
    }
  }
}).observe({type: 'layout-shift', buffered: true});

最後,如果在開發過程中無法重現版面配置問題,建議您使用 Layout Instability API 搭配您偏好的前端記錄工具,收集這些問題的更多資訊。請參閱追蹤網頁上最大偏移元素的程式碼範例