非預期的版面配置位移可能會以多種方式乾擾使用者體驗,例如:使用者在閱讀文字時突然移動,導致點選錯誤的連結或按鈕,導致閱讀中斷。在某些情況下,這可能會造成嚴重傷害。
網頁內容出現非預期的移動,通常是因為以非同步方式載入資源,或是在現有內容之前以動態方式加入 DOM 元素。版面配置位移的起因可能是尺寸不明的圖片或影片、顯示大於或小於初始備用廣告的字型,或是第三方廣告或小工具 (可自行調整大小)。
網站開發方式與使用者體驗之間的差異,則使得問題更嚴重。例如:
- 個人化或第三方內容在開發和實際工作環境中經常會有所不同。
- 開發人員的瀏覽器快取中通常已存測試圖片,但使用者載入圖片的時間可能較長。
- 在本機執行的 API 呼叫速度通常非常快,在開發過程中可能會大幅延遲開發過程中出現明顯的延遲。
「累計版面配置位移 (CLS)」指標會評估實際使用者發生這類問題的頻率,協助您解決這個問題。
什麼是 CLS?
CLS 是針對網頁整個生命週期中每個「非預期」版面配置位移,所產生最大量的版面配置位移分數分數。
每當可見元素將位置從一個已轉譯的影格變更為下一個影格時,就會發生版面配置位移。(本指南稍後會詳細說明個別版面配置位移分數的計算方式)。
大量的版面配置位移 (稱為「工作階段視窗」) 是指一或多個個別版面配置位移快速連續切換,且每次位移不到 1 秒,而總視窗持續時間最長為 5 秒。
爆發最大的工作階段是指該時段具有最高累計分數的工作階段視窗。
什麼是良好的 CLS 分數?
為了提供良好的使用者體驗,網站應力求將 CLS 分數設為 0.1 以下。為確保您大多數的使用者都能達成此目標,評估頁面載入內容的第 75 個百分位數,是針對行動裝置和電腦裝置的區隔,理想的評估門檻。
如要進一步瞭解這項建議背後的研究和方法,請參閱「定義 Core Web Vitals 指標門檻」一文。
詳細版面配置位移
版面配置位移是由 Layout Instability API 定義。每當可視區域顯示的元素改變了兩個影格之間的起始位置 (例如在預設的撰寫模式中,版面配置的頂端和左側位置) 時,這個 API 就會回報 layout-shift
項目。這類元素將視為不穩定的元素。
請注意,只有當現有元素變更起始位置時,才會發生版面配置位移。如果在 DOM 加入新元素或現有元素的大小改變,只要該變更不會造成其他可見元素變更起始位置,就不會計入版面配置位移。
版面配置位移分數
瀏覽器在計算版面配置位移分數時,會檢查可視區域的大小,以及可視區域中兩個影格之間的不穩定元素移動情形。版面配置位移分數是該移動的兩種測量結果的乘積,分別是「影響分數」和「距離分數」 (定義列於下方)。
layout shift score = impact fraction * distance fraction
影響分數
「影響分數」可用來衡量不穩定元素在兩個影格之間的可視區域區域如何影響。
特定影格的影響比例,是該影格和前一個影格所有不穩定元素的可見區域,佔可視區域總面積的佔比。
![含有一個不穩定元素的影響分數示例](https://web.developers.google.cn/static/articles/cls/image/impact-fraction-example-164341c82ee76.png?authuser=3&hl=zh-tw)
在上圖中,有一個元素在一個頁框中佔據可視區域的一半。接著,在下一個影格中,元素會將可視區域高度的 25% 向下移動。紅色虛線矩形代表兩個影格中元素可見區域的聯集。在本例中,該元素佔可視區域總數的 75%,因此影響分數為 0.75
。
距離分數
版面配置位移分數方程式的另一部分測量的是,不穩定元素相對於可視區域移動的距離。距離分數是指在頁框中移動的任何不穩定元素時,的最大水平或垂直距離,除以可視區域的最大尺寸 (寬度或高度,以較大者為準)。
![含有 1 個不穩定元素的距離分數範例](https://web.developers.google.cn/static/articles/cls/image/distance-fraction-example-9146d2a862482.png?authuser=3&hl=zh-tw)
在上述範例中,可視區域的最大尺寸為高度,不穩定的元素移動了可視區域高度 25%,因此距離比例為 0.25。
因此,在這個範例中,「影響分數」為 0.75
,「距離分數」為 0.25
,因此版面配置位移分數為 0.75 * 0.25 = 0.1875
。
範例
下一個範例將說明,將內容新增至現有元素會如何影響版面配置位移分數:
![含有多個穩定元素和不穩定元素的版面配置位移範例](https://web.developers.google.cn/static/articles/cls/image/layout-shift-example-mul-10d90b67b5d6a.png?authuser=3&hl=zh-tw)
在本範例中,灰色方塊會改變大小,但起始位置並未改變,因此不是不穩定的元素。
「按一下我!」按鈕先前不在 DOM 中,因此其起始位置也不會變更。
不過,綠色方塊的起始位置確實會改變,但由於該區域已部分移出可視區域,因此計算影響分數時不會考量隱形區域。在兩個頁框中,綠色方塊可見區域的聯集 (以紅色虛線表示) 與第一個頁框中綠色方塊的區域相同,也就是檢視點的 50%。影響分數為 0.5
。
距離分數:紫色箭頭表示。已將綠色方塊向下移動約 14% 的可視區域,因此距離比例為 0.14
。
版面配置位移分數為 0.5 x 0.14 = 0.07
。
以下範例說明多個不穩定元素如何影響網頁的版面配置位移分數:
![版面配置位移範例,含有穩定元素和__不穩定元素_,以及可視區域裁剪](https://web.developers.google.cn/static/articles/cls/image/layout-shift-example-sta-05cf93597fcee.png?authuser=3&hl=zh-tw)
在上圖的第一個影格中,動物的 API 要求有四個結果,並依字母順序排序。在第二個影格中,系統會將更多結果加入排序清單。
清單中的第一個項目 (「Cat」) 不會變更頁框之間的起始位置,因此會相當穩定。同樣地,加入清單的新項目先前也不是在 DOM 中,因此其起始位置也不會變更。但標為「狗」、「馬」和「斑馬」的項目都會改變起始位置,使元素不穩定。
同樣,紅色虛線代表這三個不穩定元素的聯集。前後各區,在本例中約佔可視區域面積的 60% (影響比例為 0.60
)。
箭頭代表不穩定的元素從起始位置移開的距離。「斑馬」元素 (以藍色箭頭表示) 移動了最多元素,約佔可視區域高度的 30%。如此一來,這個範例中的距離分數就會是 0.3
。
版面配置位移分數為 0.60 x 0.3 = 0.18
。
預期與非預期的版面配置位移
並非所有版面配置位移都會不佳。事實上,許多動態網頁應用程式經常會變更網頁上元素開始的位置。只有在使用者未預期的情況下,版面配置位移才有不良效果。
使用者啟動的版面配置位移
一般來說,只要是因使用者互動 (例如點選或輕觸連結、按下按鈕,或在搜尋框中輸入的內容) 而產生的版面配置位移,只要間隔時間夠接近使用者能夠清楚瞭解彼此間的關係即可。
舉例來說,如果使用者互動觸發的網路要求可能需要一點時間才能完成,建議您立即建立一些空間並顯示載入指標,避免在要求完成後發生版面配置位移不順暢的情況。如果使用者沒有發現正在載入的內容,或者不知道資源何時可使用,可能會在等待的同時點選其他位置,例如點選其他項目。
如果是在使用者輸入內容的 500 毫秒內進行版面配置位移,其會出現設定 hadRecentInput
旗標,因此在計算時可以排除。
動畫和轉場效果
適時調整動畫和轉場效果,是更新頁面上內容的絕佳方式,不會讓使用者感到驚訝。突然出現且突然變化的內容,通常會導致使用者體驗不佳。不過,以自然的方式從一個位置逐漸自然地移動的內容,通常有助於使用者進一步瞭解情況,並引導他們在狀態改變。
請務必遵循 prefers-reduced-motion
的瀏覽器設定,因為部分網站訪客可能會遇到動畫效果不佳的問題或註意力問題。
CSS transform
屬性可讓您在不觸發版面配置位移的情況下為元素建立動畫:
- 請不要變更
height
和width
屬性,而是使用transform: scale()
。 - 如要移動元素,請避免變更
top
、right
、bottom
或left
屬性,並改用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 指南。
其他資源
- Google 發布商廣告代碼指南:盡量減少版面配置位移
- Annie Sullivan 和 Steve Kobes 的《Understanding Cumulative Layout Shift》 (2020 年)#PerfMatters
變更記錄
有時用於測量指標的 API 中會發現錯誤,有時在指標本身的定義中也會發現錯誤。因此,有時需要進行變更,這些變更可能會在內部報表和資訊主頁中顯示為改善或迴歸。
為方便您管理,這些指標導入或定義的所有變更都會顯示在這份變更記錄中。
如果對這些指標有任何意見,歡迎透過 web-vitals-feedback Google 群組提供。