瞭解如何找出並修正版面配置偏移問題。
發布日期:2021 年 3 月 11 日,上次更新日期:2025 年 2 月 7 日
本文第一部分將介紹用於偵錯版面配置偏移的工具,第二部分則會討論如何找出版面配置偏移的原因。
工具
您可以使用版面配置不穩定 API 或 DevTools 等工具來偵錯版面配置變動,這些工具會以更容易消化的格式匯總此 API 的資料。
Layout Instability 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 組合回報版面配置偏移資訊:LayoutShift
和 LayoutShiftAttribution
介面。以下各節將詳細說明這些介面。
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 元素。在開發人員工具中將滑鼠游標懸停在這個屬性上,即可醒目顯示對應的網頁元素。
previousRect
和 currentRect
屬性會回報節點的大小和位置。
x
和y
座標分別回報元素左上角的 x 座標和 y 座標width
和height
屬性分別回報元素的寬度和高度。top
、right
、bottom
和left
屬性會回報與元素指定邊緣相對應的 x 或 y 座標值。換句話說,top
的值等於y
;bottom
的值等於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 開發人員工具效能面板的即時指標畫面中顯示版面配置位移記錄。](https://web.developers.google.cn/static/articles/debug-layout-shifts/image/live-metrics-cls.png?hl=zh-tw)
一旦您能夠可靠地重現版面配置偏移,就可以執行追蹤作業,取得更多詳細資料:
![Chrome 開發人員工具效能面板中顯示的版面配置位移記錄。](https://web.developers.google.cn/static/articles/debug-layout-shifts/image/devtools-cls-debugging.png?hl=zh-tw)
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 樣式,或是載入及套用網頁字型。
![圖表顯示字型交換造成的版面配置變動](https://web.developers.google.cn/static/articles/debug-layout-shifts/image/diagram-showing-layout-s-60ec3d8c95616.png?hl=zh-tw)
以下是一些最常導致版面配置位移事件的特定行為:
元素位置的變更 (非因其他元素的移動而變更)
這類變更通常是因為:
- 較晚載入的樣式表,或覆寫先前宣告的樣式。
- 動畫和轉場效果。
元素的尺寸變更
這類變更通常是因為:
- 較晚載入的樣式表,或覆寫先前宣告的樣式。
- 圖片和 iframe 沒有
width
和height
屬性,且在「插槽」算繪後載入。 - 不含
width
或height
屬性的文字區塊,會在文字算繪後交換字型。
插入或移除 DOM 元素
這通常是因為:
- 插入廣告和其他第三方嵌入內容。
- 插入橫幅、快訊和模式。
- 無限捲動和其他 UX 模式,會在現有內容上方載入額外內容。
觸發版面配置的動畫
某些動畫效果可觸發版面配置。這類常見的例子是,DOM 元素透過遞增 top
或 left
等屬性而非使用 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 搭配您偏好的前端記錄工具,收集這些問題的更多資訊。請參閱追蹤網頁上最大偏移元素的程式碼範例。