網站開發人員以往是挑戰網頁的主要內容,要測量網頁主要內容何時載入並向使用者顯示。
load 或 DOMContentLoaded 等舊版指標並不理想,因為這些指標不一定符合使用者在螢幕上看到的內容。此外,「First Contentful Painint (FCP)」等以使用者為中心的較新成效指標,只會記錄載入體驗的起點。如果頁面顯示啟動畫面或顯示載入指標,這個時刻對使用者來說並不實用。
過去,我們推薦首次測量繪製 (FMP) 和速度指數 (SI) 等成效指標,協助在初始繪製後擷取更多的載入體驗,但這些指標複雜、難以解釋,通常也很糟糕,這表示在載入頁面主要內容時,這些指標仍難以辨識。
有時候,越簡單越好。根據 W3C Web Performance Working Group 的討論以及 Google 進行的研究,我們發現更準確地評估網頁載入主要內容的時間點,是查看轉譯最大元素的時間。
什麼是 LCP?
「最大內容繪製 (LCP)」指標會回報可視區域中最大圖片或文字區塊顯示時間 (相對於使用者首次前往頁面的時間)。
什麼是良好的 LCP 分數?
為了提供良好的使用者體驗,網站應力求最大內容繪製 2.5 秒以下。為確保您大多數使用者都達成這個目標,評估門檻是網頁載入的第 75 個百分位數,並按不同區隔的行動裝置和電腦裝置進行區隔。
哪些元素會列入考量?
根據目前在最大內容繪製 API 中指定的內容,系統考慮為最大內容繪製時考量的元素類型如下:
<img>
個元素<svg>
元素中的<image>
元素- 包含海報圖片的
<video>
元素 (會使用代表圖片載入時間) - 透過
url()
函式載入背景圖片的元素 (而非 CSS 漸層) - 區塊層級元素,包含文字節點或其他內嵌層級文字元素子項。
- 為自動播放
<video>
元素繪製的第一個影格 (截至 2023 年 8 月) - 動畫圖片格式的第一個影格,例如動畫 GIF (截至 2023 年 8 月)
請注意,為了簡化整個影片開頭,我們刻意將元素限制在這組受限組合。日後我們可能會陸續加入其他元素,例如完整的 <svg>
支援。
除了考量某些元素外,系統也會套用某些經驗法則,排除可能視為「非內容」的特定元素。針對以 Chromium 為基礎的瀏覽器,這些瀏覽器包括:
- 不透明度為 0 的元素,使用者無法看見的元素
- 覆蓋整個可視區域的元素,可能會被視為背景,而不是內容
- 預留位置圖片或其他熵不足的圖片,可能無法反映網頁的實際內容
為提供使用者期望的最大「內容」元素,瀏覽器會持續改善這些經驗法則。
這些「內容性」經驗法則可能與首次顯示內容所需時間 (FCP) 所使用的不同,後者可能會將其中部分元素 (例如預留位置圖片或完整可視區域圖片) 納入考量,即使這些元素不符合 LCP 候選人的資格也一樣。雖然兩者的名稱都使用「內容豐富」,但目的不同。FCP 會評估在網頁繪製主要內容時,任何內容繪製到畫面和 LCP 的時機,因此 LCP 應使用更為選擇性。
元素大小的決定方式為何?
針對最大內容繪製回報的元素大小,通常是使用者在可視區域中可看見的大小。如果元素超出可視區域範圍,或是任一元素遭到裁剪或出現不可見的overflow,這些部分就不會計入元素的大小。
如果圖片元素根據內在尺寸調整大小,系統回報的大小就會是可見尺寸或內建函式大小 (以較小者為準)。例如,縮減到比內建函式尺寸小很多的圖片,只會回報顯示大小,而延伸或展開至較大尺寸的圖片只會回報其內建函式尺寸。
對於文字元素,系統只會考慮文字節點的大小 (涵蓋所有文字節點的最小矩形)。
所有元素都不會考慮透過 CSS 套用的邊界、邊框間距或框線。
何時會回報最大內容繪製?
網頁通常會分階段載入,因此網頁上最大的元素可能會改變。
為處理這個潛在的變動,瀏覽器會在瀏覽器繪製第一個影格後,立即分派 largest-contentful-paint
類型的 PerformanceEntry
,識別最大內容元素。但是,在轉譯後續影格後,每當最大的內容元素變更時,系統就會分派另一個 PerformanceEntry
。
舉例來說,當網頁含有文字和主頁橫幅時,瀏覽器一開始可能會算繪文字,這時瀏覽器會分派 largest-contentful-paint
項目,而 element
屬性可能會參照 <p>
或 <h1>
。稍後,主頁橫幅載入完畢後,系統會分派第二個 largest-contentful-paint
項目,其 element
屬性會參照 <img>
。
請注意,只有在元素轉譯並向使用者顯示後,才能視為最大內容元素。尚未載入的圖片不會視為「已轉譯」。在字型區塊期間中,都不是使用網頁字型的文字節點。在這種情況下,系統可能會將較小的元素回報為最大內容元素,但等較大的元素算繪完成後,就會透過其他 PerformanceEntry
物件回報。
除了延遲載入圖片和字型外,當有新內容可供使用時,網頁也可能會在 DOM 中加入新元素。如有任何新元素大於前一個最大的內容元素,系統也會回報新的 PerformanceEntry
。
如果目前是最大內容元素的元素已從可視區域中移除 (甚至從 DOM 中移除),那麼除非算繪較大的元素,否則該元素仍會是最大的內容元素。
使用者與網頁互動後 (透過輕觸、捲動或按鍵),瀏覽器會停止回報新項目,因為使用者互動通常會改變使用者可見的內容 (這種情況在捲動畫面時尤其明顯)。
為了進行分析,請只將最近分派的 PerformanceEntry
回報給數據分析服務。
載入時間與轉譯時間
基於安全考量,缺少 Timing-Allow-Origin
標頭的跨來源圖片不會公開圖片的轉譯時間戳記。而是只會公開載入時間 (因為已透過許多其他網頁 API 公開)。
這可能會導致明顯不可能的情況,也就是網頁 API 回報 LCP 的時間比 FCP 更早。不過,受到這項安全性限制的影響,實際情況並非如此。
建議您盡可能設定 Timing-Allow-Origin
標頭,以便提高指標的準確性。
系統如何處理元素版面配置和大小變更?
為了降低計算和分派新效能項目的效能負擔,變更元素大小或位置並不會產生新的 LCP 候選項目。系統只會考量元素的初始大小和可視區域中的位置。
這表示系統可能不會回報一開始算繪畫面外的圖片。這也代表一開始在可視區域算繪後,隨後向下而向下的元素,仍會回報在可視區域中的初始大小。
範例
以下列舉幾個熱門網站上出現最大內容繪製情況的範例:
在上述兩個時間軸中,最大的元素會在內容載入時變更。在第一個範例中,新內容會加入 DOM,並變更最大元素。在第二個範例中,版面配置變更和先前最大的內容會從可視區域中移除。
雖然延遲載入的內容通常比網頁上的內容還要大,但這不一定是如此。接下來的兩個例子是在頁面完全載入前發生的最大內容繪製情況。
在第一個範例中,Instagram 標誌會相對提早載入,即使系統會逐步顯示其他內容,仍保有最大的元素。在 Google 搜尋結果網頁範例中,最大的元素是一段文字,會在任何圖片或標誌載入完成前顯示。由於所有個別圖片都小於此段落,因此在整個載入過程中,它會保持最大的元素。
如何測量 LCP
LCP 可在研究室或實際領域中測量,下列工具中的工具皆可使用:
欄位工具
研究室工具
評估 JavaScript 的 LCP
如要測量以 JavaScript 呈現的 LCP,您可以使用最大內容繪製 API。以下範例說明如何建立 PerformanceObserver
來監聽 largest-contentful-paint
項目,並將其記錄到控制台。
new PerformanceObserver((entryList) => {
for (const entry of entryList.getEntries()) {
console.log('LCP candidate:', entry.startTime, entry);
}
}).observe({type: 'largest-contentful-paint', buffered: true});
在上述範例中,每個記錄的 largest-contentful-paint
項目都代表目前的 LCP 候選項目。一般而言,發出的最後一個項目的 startTime
值是 LCP 值,但不一定是各種情況。並非所有 largest-contentful-paint
項目都對評估 LCP 有效。
以下章節列出 API 報表與指標計算方式之間的差異。
指標與 API 之間的差異
- API 會針對在背景分頁中載入的頁面分派
largest-contentful-paint
項目,但在計算 LCP 時,應忽略這些網頁。 - API 會在頁面於背景執行後繼續分派
largest-contentful-paint
項目,但在計算 LCP 時應忽略這些項目 (只有在頁面完全處於前景時,才會考慮元素)。 - 當頁面從往返快取還原時,API 不會回報
largest-contentful-paint
項目,但在這種情況下,應評估 LCP,因為使用者會體驗到不同的網頁造訪次數。 - API 不會考慮 iframe 內的元素,但指標的呈現效果是網頁使用者體驗的一部分。在 iframe 內包含 LCP 的網頁 (例如內嵌影片中的海報圖片) 中,會顯示 CrUX 與 RUM 的差異。如要正確測量 LCP,請考量這些內容。子頁框可以使用 API 將
largest-contentful-paint
項目回報給上層頁框進行匯總。 - API 會從導覽開始時測量 LCP,但如果是預先轉譯的頁面 LCP,則應使用
activationStart
進行評估,因為會對應使用者遇到的 LCP 時間。
開發人員可以使用 web-vitals
JavaScript 程式庫測量 LCP,而不是只強調這些細微差異,後者會為您處理這些差異 (請注意,iframe 問題並不適用):
import {onLCP} from 'web-vitals';
// Measure and log LCP as soon as it's available.
onLCP(console.log);
如要瞭解如何以 JavaScript 測量 LCP,請參閱 onLCP()
的原始碼。
如果最大的元素並不重要,該怎麼辦?
在某些情況下,網頁上最重要的元素 (或元素) 與大型元素不同,開發人員可能會更想評估這些其他元素的轉譯時間。您可以使用 Element Timing API 來達到此目的,請參閱「自訂指標」一文。
如何改善 LCP
請參閱最佳化 LCP 的完整指南,瞭解如何找出現場 LCP 時間,並使用研究室資料細查和最佳化時間。
其他資源
- Annie Sullivan 在 performance.now() 的 Chrome 效能監控方法學習 (2019 年)
網誌
偶爾會在用來評估指標的 API 中發現錯誤,有時也會發生指標本身定義。因此,有時您必須進行調整,內部報表和資訊主頁中都會顯示這類變更來改善或迴歸。
為協助您管理這種情況,這些指標的導入或定義都會在這份 CHANGELOG 中顯示。
如果您對這些指標有任何意見回饋,歡迎在 web-vitals-feedback Google 群組中提出。