Cumulative Layout Shift (CLS)

米莉卡 (Milica Mihajlija)
Milica Mihajlija
菲利普.沃爾頓 (Philip Walton)
Philip Walton

瀏覽器支援

  • 77
  • 79
  • x
  • x

資料來源

您是否曾在線上閱讀文章時,發現網頁上的內容突然改變?如未收到警告,文字會移動,導致你迷失指定位置。更糟的是,你要輕觸連結或按鈕,卻在手指浮現前瞬間移動,因為連結就移動了,導致你點選了其他東西。

大多數這類體驗都讓人感到困擾,但在某些情況下,可能會造成實質損失。

螢幕側錄說明版面配置不穩定性會對使用者造成負面影響。

網頁內容在非預期的情況下移動,通常是因為系統以非同步方式載入資源,或讓 DOM 元素在現有內容上方動態加入頁面。問題可能是圖片或影片具有不明尺寸、顯示大於或小於備用廣告的字型,或是會動態調整大小的第三方廣告或小工具。

這個問題造成更嚴重的原因是網站在開發中的運作方式,與使用者遇到的狀況通常大不相同。個人化或第三方內容在開發過程中的行為通常與實際工作環境不同,測試圖片通常都已納入開發人員的瀏覽器快取中,而在本機執行的 API 呼叫通常會過於快,因此你無法注意到延遲情形。

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

什麼是 CLS?

CLS 會評估在網頁整個生命週期發生的非預期版面配置位移,進而產生最大爆發的版面配置位移分數

每當可見元素變更其位置從一個轉譯影格到下一個轉譯影格的位置,就會發生「版面配置位移」。(如要進一步瞭解個別版面配置位移分數的計算方式,請參閱下文)。

稱為「工作階段回溯期」的爆發版面配置位移,是指一或多個個別版面配置快速連續轉換,每個轉動期間不到 1 秒,到總時長最多 5 秒。

最大的爆發是工作階段期間,該期間內所有版面配置位移的累計分數上限。

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

什麼是 CLS 分數?

為了提供優質的使用者體驗,網站應力求讓 CLS 分數為 0.1 以下。為確保大部分使用者都能達成這個目標,適合評估的良好門檻是網頁載入的第 75 個百分位數 (以行動裝置和電腦裝置劃分)。

良好的 CLS 值小於 0.1,不良值大於 0.25,還有需要改善之間的任何值

版面配置位移詳細資訊

版面配置轉移是由版面配置不一致 API 定義,每當可視區域中顯示的元素變更起始位置 (例如預設寫入模式的頂端和左側位置) 之間,就會回報 layout-shift 項目。這類元素可視為不穩定的元素

請注意,只有在現有元素變更起始位置時,才會發生版面配置位移。如果將新元素新增至 DOM,或現有元素改變大小,則只要變更內容不會造成其他可見元素改變其起始位置,系統不會計入版面配置位移。

版面配置位移分數

計算版面配置位移分數時,瀏覽器會查看可視區域大小,以及兩個轉譯影格之間「不穩定元素」的移動情形。版面配置位移分數是該移動度的兩項測量結果的產物,分別是「有效比例」和「距離比例」 (兩者定義如下)。

layout shift score = impact fraction * distance fraction

影響比例

影響比例會測量「不穩定元素」對兩個影格之間的可視區域有何影響。

上一個影格「和」目前影格的所有「不穩定元素」可見區域組成的聯集,是目前影格的「影響比例」

包含一個「不穩定」元素的影響分數範例

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

距離分數

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

包含一個「不穩定」元素的距離比例範例_

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

因此,在本範例中,impactMile0.75distance 深度0.25,因此版面配置位移分數0.75 * 0.25 = 0.1875

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

含有多個穩定元素和「不穩定」元素的版面配置位移範例

「Click Me!」按鈕會附加到灰色方塊底部,其中含有黑色文字,這會將綠色方塊向下推 (並傳出部分可視區域)。

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

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

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

距離比例以紫色箭頭表示。綠色方塊已減少約 14% 的可視區域,因此「distancesnack」0.14

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

本最後一個範例說明多個不穩定的元素

含有穩定元素和_不穩定元素_和可視區域裁剪的版面配置位移範例

上方第一個頁框中有四個動物的 API 要求結果,結果會依字母順序排序。在第二個影格中,系統會在排序後的清單新增更多結果。

清單中的第一個項目 (「Cat」) 不會變更影格之間的起始位置,因此形狀穩定。同樣地,新增至清單的新項目以前不在 DOM 中,因此起始位置也不會改變。不過,標記為「Dog」、「Horse」和「Zebra」的項目會改變其起始位置,導致這些元素不穩定

再次強調,紅色虛線矩形代表這三個「不穩定元素」的聯集,因此在這個例子中,約佔可視區域面積的 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 API 的限制下,web vitals JavaScript 程式庫盡可能在能力範圍內處理上述作業。

指標與 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 中發現錯誤,有時在指標本身的定義中會發現錯誤。因此,您有時必須做出調整,這些變更在內部報表和資訊主頁中可能會顯示為改善或迴歸狀況。

為了協助您管理這項功能,我們對這些指標的導入方式或定義所做的變更,都會顯示在這個 CHANGELOG 中。

如果你對這些指標有任何意見,可以在 web-vitals-feedback 中提供該指標。