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 還會評估網頁的整個生命週期,因此會更加複雜:

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

為處理這類情況,除了在網頁卸載時,當網頁處於背景時也應回報 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 群組提供意見。