Cumulative Layout Shift (CLS)

Milica Mihajlija
Milica Mihajlija

瀏覽器支援

  • 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。

如要進一步瞭解這項建議背後的研究和方法,請參閱定義網站體驗核心指標門檻一文。

版面配置位移的詳細資訊

版面配置位移是由 Layout Instability API 定義,每當在可視區域內顯示的元素改變了起始位置 (例如寫入模式的頂端和左側位置) 時,此 API 就會回報 layout-shift 項目。這類元素會視為「不穩定」

請注意,只有在現有元素變更起始位置時,才會發生版面配置位移。如果將新元素加入 DOM 或現有元素大小改變,只要該變更不會導致其他顯示元素改變起始位置,就不會計入版面配置位移。

版面配置位移分數

為計算版面配置位移分數,瀏覽器會檢視可視區域的大小,以及可視區域在兩個轉譯影格之間的「不穩定元素」移動情形。版面配置位移分數是兩個測量動作的乘積:影響比例距離比例 (皆定義如下)。

layout shift score = impact fraction * distance fraction

影響比例

影響比例測量的是不穩定的元素對兩個頁框之間的可視區域區域有何影響。

在特定影格的影響部分,是將該影格與前一幅影格所有不穩定元素的可見區域組合,並將其佔可視區域總區域的比例。

含有 1 個不穩定元素的影響比例範例
如果元素的位置改變,則元素先前及其目前的位置都會影響其影響分數。

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

距離分數

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

含有一個不穩定元素的距離分數範例
距離比例代表元素在可視區域移動的距離。

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

因此,本例中的影響比例0.75距離比例0.25,因此版面配置位移分數0.75 * 0.25 = 0.1875

示例

下一個範例說明瞭在現有元素中新增內容對版面配置位移分數有何影響:

含有多個穩定版和_不 table 元素的版面配置位移範例_
在灰色方塊底部新增按鈕,將綠色方塊向下推,並到達可視區域。

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

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

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

距離比例則以紫色箭頭表示。綠色方塊已將可視區域的 14% 下移,因此距離比例0.14

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

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

含有穩定版和「不穩定元素」和可視區域裁剪的版面配置位移範例
隨著這份排序清單中出現更多姓名,現有名稱也會移動,讓名稱保持按照字母順序排列。

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

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

同樣地,紅色虛線矩形代表三個「不穩定元素」的聯集,在本案例中是大約可視區域區域 60% 的聯集 (影響比例)。0.60

箭頭代表不穩定元素從起始位置移開的距離。藍色箭頭代表的「Zebra」元素已移動最多,佔可視區域高度的 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,您必須考慮 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 群組提出。