Cumulative Layout Shift (CLS)

瀏覽器支援

  • Chrome:77。
  • Edge:79。
  • Firefox:不支援。
  • Safari:不支援。

資料來源

未預期的版面配置變更可能會以多種方式影響使用者體驗,例如當文字突然移動時,使用者可能會在閱讀時迷失方向,或是誤點連結或按鈕。在某些情況下,這可能會造成嚴重損壞。

版面配置突然改變,導致使用者確認原本想取消的大訂單。

資源非同步載入或 DOM 元素在現有內容之前動態新增至網頁時,通常會發生網頁內容非預期移動的情形。造成版面配置偏移的原因可能是圖片或影片的尺寸不明、字型顯示的大小大於或小於初始備用項,或是第三方廣告或小工具會動態調整大小。

網站開發人員和使用者體驗的差異,會讓這個問題更加嚴重。例如:

  • 個人化或第三方內容在開發和實際運作時,通常會呈現不同的行為。
  • 測試圖片通常已存在開發人員的瀏覽器快取中,但對使用者來說,載入時間會更長。
  • 在本機執行的 API 呼叫通常速度非常快,因此在開發階段不易察覺的延遲,可能會在實際工作環境中變得相當明顯。

累積版面配置偏移 (CLS) 指標可評估實際使用者發生這類問題的頻率,協助您解決這個問題。

什麼是 CLS?

CLS 是一種評估指標,可針對網頁整個生命週期發生的每一次非預期版面配置位移,評估最快速密集的版面配置位移分數

當可見元素從一個已算繪影格變更至下一個影格時,就會發生版面配置轉移。(詳情請參閱本指南後續章節,瞭解如何計算個別版面配置位移分數)。

一連串的版面配置轉換 (稱為工作階段時間區間) 是指一或多個個別版面配置轉換快速接續發生,且每個轉換之間的間隔時間少於 1 秒,且總時間區間長度上限為 5 秒。

最嚴重的爆發事件,是工作階段期間內,所有版面配置位移的累計分數最高的時間區間。

工作階段視窗範例。藍色長條代表各個版面配置位移的分數。

什麼是良好的 CLS 分數?

為了提供良好的使用者體驗,網站應力求 CLS 分數為 0.1 以下。為確保多數使用者都能享有此等級的體驗,建議您以第 75 個百分位數做為門檻,評估網頁載入情形,並區分行動裝置和電腦。

良好的 CLS 值為 0.1 以下,不良的值大於 0.25,介於兩者之間的值則需要改善
良好的 CLS 值為 0.1 以下。高值大於 0.25。

如要進一步瞭解這項最佳化建議背後的研究和方法,請參閱「定義 Core Web Vitals 指標門檻」。

版面配置位移詳細資訊

版面配置偏移是由 Layout Instability API 定義,當可視區域內的可見元素在兩個影格之間變更其起始位置 (例如預設 writing mode 中的頂端和左側位置) 時,就會回報 layout-shift 項目。這類元素會視為不穩定元素

請注意,只有在現有元素變更起始位置時,才會發生版面配置變更。如果 DOM 中新增元素或現有元素變更大小,只要變更不會導致其他可見元素變更起始位置,就不會視為版面配置變動。

版面配置位移分數

為了計算版面配置位移分數,瀏覽器會查看可視區域大小,以及兩個轉譯影格之間可視區域中不穩定元素的移動情形。版面配置移動分數是移動的兩個測量值相乘的結果:影響因子距離因子 (兩者皆在下方定義)。

layout shift score = impact fraction * distance fraction

影響因子

影響因子會評估不穩定元素對兩個影格之間可視區域的影響程度。

特定影格影響因子的計算方式,是將該影格和前一個影格中所有不穩定元素的可見區域相加,再除以檢視區的總面積。

影響因子示例:一個不穩定的元素
如果元素變更位置,其影響因子會受到其先前和目前位置的影響。

在上述圖片中,有一個元素會佔用單一影格中一半的檢視區範圍。接著,在下一個影格中,元素會向下移動 25% 的可視區域高度。紅色虛線矩形表示兩個影格中元素可見區域的聯集,在本例中,這項聯集占總檢視區的 75%,因此其影響因子0.75

距離分數

版面配置轉移分數公式的另一部分,是用來測量不穩定元素相對於可視區域移動的距離。距離分數是指任何不穩定元素在影格中移動的最大水平或垂直距離,除以可視區域的最大尺寸 (寬度或高度,以較大者為準)。

距離分數範例 (含有一個不穩定元素)
距離百分比是指元素在可視區域內移動的距離。

在前述範例中,可視區域的最大尺寸是高度,不穩定元素已移動了可視區域高度的 25%,因此距離分數為 0.25。

因此,在這個範例中,影響分數0.75距離分數0.25,因此版面配置移位分數0.75 * 0.25 = 0.1875

範例

下列範例說明在現有元素中新增內容會如何影響版面配置位移分數:

包含多個穩定和不穩定元素的版面配置變動範例
在灰色方塊底部新增按鈕會將綠色方塊往下推,並且部分超出可視區域。

在這個範例中,灰色方塊會變更大小,但其起始位置不會變更,因此不是不穩定的元素

「Click Me!」按鈕先前不在 DOM 中,因此其開始位置也不會變更。

不過,綠色方塊的起始位置確實會改變,但由於該方塊已部分移出檢視區,因此計算影響比率時,不會考量看不見的區域。兩個影格中綠色方塊的可見區域 (以紅色虛線矩形表示) 的聯集,與第一個影格中綠色方塊的區域相同,即檢視區域的 50%。影響因子0.5

距離分數以紫色箭頭表示。綠色方塊已向下移動約 14% 的可視區域,因此距離分數0.14

版面配置位移分數為 0.5 x 0.14 = 0.07

以下範例說明多個不穩定元素如何影響網頁的版面配置偏移分數:

版面配置轉移範例:含有穩定和不穩定元素,以及可視區域裁剪
在這個排序清單中,隨著更多名稱出現,現有名稱會移動,以便維持字母順序。

在上圖的第一個畫面中,有四個動物 API 要求的結果,並依字母順序排序。在第二個畫面中,排序清單會新增更多結果。

清單中的第一個項目 (「Cat」) 在影格之間不會變更其起始位置,因此是穩定的。同樣地,新增至清單的新項目先前並未在 DOM 中,因此其開始位置也不會變更。但標示為「Dog」、「Horse」和「Zebra」的項目都會改變起始位置,因此屬於不穩定元素

同樣地,紅色虛線矩形代表這三個不穩定元素前後區域的聯集,在本例中約為檢視區域的 60% (0.60影響比率)。

箭頭代表不穩定元素從起始位置移動的距離。以藍色箭頭表示的「斑馬」元素移動幅度最大,約為可視區高度的 30%。因此,本範例中的距離分數0.3

版面配置位移分數為 0.60 x 0.3 = 0.18

預期與非預期的版面配置轉移

並非所有版面配置變更都是不好的。事實上,許多動態網站應用程式經常變更網頁上元素的起始位置。只有在使用者未預期的情況下,版面配置位移才會造成不良影響。

使用者啟動的版面配置位移

只要在使用者互動 (例如點選連結、按下按鈕或在搜尋框中輸入內容) 後,布局變動情形不明顯,就不會違反規範。

舉例來說,如果使用者互動觸發的網路要求可能需要一段時間才能完成,建議您盡快建立一些空間並顯示載入指標,以免在要求完成時造成不佳的版面配置變更。如果使用者不知道系統正在載入內容,或是不知道資源何時會就緒,可能會在等待期間嘗試點選其他項目,而這些項目可能會在等待期間移除。

在使用者輸入內容後的 500 毫秒內發生的版面配置變動會設定 hadRecentInput 標記,因此可從計算中排除。

動畫和轉場效果

動畫和轉場效果做得好,就能在更新網頁內容時不讓使用者感到意外。內容在頁面上突然且意外地移動,幾乎總是會導致使用者體驗不佳。不過,如果內容能自然地從一個位置移動到下一個位置,通常能幫助使用者進一步瞭解發生的情況,並引導他們在狀態變更之間切換。

請務必尊重 prefers-reduced-motion 瀏覽器設定,因為部分網站訪客可能會因動畫產生不良影響或注意力問題。

您可以使用 CSS transform 屬性為元素設定動畫,而不會觸發版面配置變更:

  • 請改用 transform: scale(),而非變更 heightwidth 屬性。
  • 如要移動元素,請避免變更 toprightbottomleft 屬性,改用 transform: translate()

如何評估 CLS

CLS 可在實驗室實際環境中進行評估,並可透過下列工具評估:

欄位工具

實驗室工具

在 JavaScript 中測量版面配置位移

如要評估 JavaScript 中的版面配置位移,請使用 Layout Instability API

以下範例說明如何建立 PerformanceObserver,以便將 layout-shift 項目記錄到主控台:

new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    console.log('Layout shift:', entry);
  }
}).observe({type: 'layout-shift', buffered: true});

在 JavaScript 中評估 CLS

如要評估 JavaScript 中的 CLS,您必須將這些意外的 layout-shift 項目分組為工作階段,並計算最大工作階段值。您可以參考 web vitals JavaScript 程式庫原始碼,其中包含 CLS 計算方式的參考實作項目。

在大多數情況下,網頁卸載時的目前 CLS 值就是該網頁的最終 CLS 值,但也有幾個重要的例外狀況,請參閱下一節。web vitals JavaScript 程式庫會在 Web API 限制範圍內,盡可能納入這些項目。

指標和 API 的差異

  • 如果網頁是在背景中載入,或是在瀏覽器繪製任何內容之前就處於背景狀態,則不應回報任何 CLS 值。
  • 如果系統從後退/前進快取還原網頁,則應將 CLS 值重設為零,因為使用者會將此視為不同的網頁瀏覽。
  • 對於在 iframe 中發生的轉換,API 不會回報 layout-shift 項目,但指標會回報,因為指標是網頁使用者體驗的一部分。這可能顯示為 CrUX 和 RUM 之間的差異。如要正確評估 CLS,請考慮這些因素。子畫面可以使用 API 將其 layout-shift 項目回報給父項畫面,以便匯總

除了這些例外狀況之外,CLS 還會評估網頁的整個生命週期,因此會更加複雜:

  • 使用者可能會將分頁開啟一段長的時間,例如數天、數週或數月。事實上,使用者可能從未關閉分頁。
  • 在行動作業系統上,瀏覽器通常不會針對背景分頁執行網頁卸載回呼,因此很難回報「final」值。

為處理這類情況,除了在網頁卸載時之外,當網頁處於背景時,也應回報 CLS (visibilitychange 事件涵蓋這兩種情況)。接收這類資料的分析系統,則需要在後端計算最終 CLS 值。

開發人員可以使用 web-vitals JavaScript 程式庫來評估 CLS,這樣就不必自己背誦並處理所有這些情況 (除了 iframe 情況):

import {onCLS} from 'web-vitals';

// Measure and log CLS in all situations
// where it needs to be reported.
onCLS(console.log);

如何改善 CLS

如要進一步瞭解如何在實務中找出版面配置位移,並使用實驗室資料進行最佳化,請參閱最佳化 CLS 指南。

其他資源

變更記錄

有時,我們會在用於評估指標的 API 中發現錯誤,有時也會在指標定義中發現錯誤。因此,有時必須進行變更,這些變更可能會在內部報表和資訊主頁中顯示為改善或回歸。

為協助您管理這項情況,我們會在這個變更記錄中顯示這些指標的導入方式或定義所做的所有變更。

如果您對這些指標有任何意見,歡迎前往 web-vitals-feedback Google 群組提供意見。