Cumulative Layout Shift (CLS)

瀏覽器支援

  • 77
  • 79
  • x
  • x

資料來源

非預期的版面配置位移可能會以多種方式乾擾使用者體驗,例如:使用者在閱讀文字時突然移動,導致點選錯誤的連結或按鈕,導致閱讀中斷。在某些情況下,這可能會造成嚴重傷害。

版面配置突然改變,可讓使用者確認預期的顯示順序。 即可取消。

網頁內容出現非預期的移動,通常是因為以非同步方式載入資源,或是在現有內容之前以動態方式加入 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 定義。每當可視區域顯示的元素改變了兩個影格之間的起始位置 (例如在預設的撰寫模式中,版面配置的頂端和左側位置) 時,這個 API 就會回報 layout-shift 項目。這類元素將視為不穩定的元素

請注意,只有當現有元素變更起始位置時,才會發生版面配置位移。如果在 DOM 加入新元素或現有元素的大小改變,只要該變更不會造成其他可見元素變更起始位置,就不會計入版面配置位移。

版面配置位移分數

瀏覽器在計算版面配置位移分數時,會檢查可視區域的大小,以及可視區域中兩個影格之間的不穩定元素移動情形。版面配置位移分數是該移動的兩種測量結果的乘積,分別是「影響分數」和「距離分數」 (定義列於下方)。

layout shift score = impact fraction * distance fraction

影響分數

「影響分數」可用來衡量不穩定元素在兩個影格之間的可視區域區域如何影響。

特定影格的影響比例,是該影格和前一個影格所有不穩定元素的可見區域,佔可視區域總面積的佔比。

含有一個不穩定元素的影響分數示例
如果元素改變位置,其先前和目前位置都會影響其影響分數。

在上圖中,有一個元素在一個頁框中佔據可視區域的一半。接著,在下一個影格中,元素會將可視區域高度的 25% 向下移動。紅色虛線矩形代表兩個影格中元素可見區域的聯集。在本例中,該元素佔可視區域總數的 75%,因此影響分數0.75

距離分數

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

含有 1 個不穩定元素的距離分數範例
距離分數會測量元素在可視區域移動的距離。

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

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

範例

下一個範例將說明,將內容新增至現有元素會如何影響版面配置位移分數:

含有多個穩定元素和不穩定元素的版面配置位移範例
在灰色方塊底部新增按鈕,會將綠色方塊向下推動,部分從檢視點外推。

在本範例中,灰色方塊會改變大小,但起始位置並未改變,因此不是不穩定的元素

「按一下我!」按鈕先前不在 DOM 中,因此其起始位置也不會變更。

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

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

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

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

版面配置位移範例,含有穩定元素和__不穩定元素_,以及可視區域裁剪
隨著此排序清單上顯示的名稱越來越多,現有名稱將繼續保持字母順序。

在上圖的第一個影格中,動物的 API 要求有四個結果,並依字母順序排序。在第二個影格中,系統會將更多結果加入排序清單。

清單中的第一個項目 (「Cat」) 不會變更頁框之間的起始位置,因此會相當穩定。同樣地,加入清單的新項目先前也不是在 DOM 中,因此其起始位置也不會變更。但標為「狗」、「馬」和「斑馬」的項目都會改變起始位置,使元素不穩定

同樣,紅色虛線代表這三個不穩定元素的聯集。前後各區,在本例中約佔可視區域面積的 60% (影響比例0.60)。

箭頭代表不穩定的元素從起始位置移開的距離。「斑馬」元素 (以藍色箭頭表示) 移動了最多元素,約佔可視區域高度的 30%。如此一來,這個範例中的距離分數就會是 0.3

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

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

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

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

一般來說,只要是因使用者互動 (例如點選或輕觸連結、按下按鈕,或在搜尋框中輸入的內容) 而產生的版面配置位移,只要間隔時間夠接近使用者能夠清楚瞭解彼此間的關係即可。

舉例來說,如果使用者互動觸發的網路要求可能需要一點時間才能完成,建議您立即建立一些空間並顯示載入指標,避免在要求完成後發生版面配置位移不順暢的情況。如果使用者沒有發現正在載入的內容,或者不知道資源何時可使用,可能會在等待的同時點選其他位置,例如點選其他項目。

如果是在使用者輸入內容的 500 毫秒內進行版面配置位移,其會出現設定 hadRecentInput 旗標,因此在計算時可以排除。

動畫和轉場效果

適時調整動畫和轉場效果,是更新頁面上內容的絕佳方式,不會讓使用者感到驚訝。突然出現且突然變化的內容,通常會導致使用者體驗不佳。不過,以自然的方式從一個位置逐漸自然地移動的內容,通常有助於使用者進一步瞭解情況,並引導他們在狀態改變。

請務必遵循 prefers-reduced-motion 的瀏覽器設定,因為部分網站訪客可能會遇到動畫效果不佳的問題或註意力問題。

CSS transform 屬性可讓您在不觸發版面配置位移的情況下為元素建立動畫:

  • 請不要變更 heightwidth 屬性,而是使用 transform: scale()
  • 如要移動元素,請避免變更 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 值重設為零,因為使用者只會將系統視為不重複網頁造訪。
  • API 不會回報 iframe 內發生偏移的 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 群組提供。