Largest Contentful Paint (LCP)

沃爾頓 (Philip Walton)
Philip Walton
巴瑞帕拉德
Barry Pollard

瀏覽器支援

  • 77
  • 79
  • x
  • x

資料來源

網站開發人員以往是挑戰網頁的主要內容,要測量網頁主要內容何時載入並向使用者顯示。

loadDOMContentLoaded 等舊版指標並不理想,因為這些指標不一定符合使用者在螢幕上看到的內容。此外,「First Contentful Painint (FCP)」等以使用者為中心的較新成效指標,只會記錄載入體驗的起點。如果頁面顯示啟動畫面或顯示載入指標,這個時刻對使用者來說並不實用。

過去,我們推薦首次測量繪製 (FMP)速度指數 (SI) 等成效指標,協助在初始繪製後擷取更多的載入體驗,但這些指標複雜、難以解釋,通常也很糟糕,這表示在載入頁面主要內容時,這些指標仍難以辨識。

有時候,越簡單越好。根據 W3C Web Performance Working Group 的討論以及 Google 進行的研究,我們發現更準確地評估網頁載入主要內容的時間點,是查看轉譯最大元素的時間。

什麼是 LCP?

「最大內容繪製 (LCP)」指標會回報可視區域中最大圖片或文字區塊顯示時間 (相對於使用者首次前往頁面的時間)。

什麼是良好的 LCP 分數?

為了提供良好的使用者體驗,網站應力求最大內容繪製 2.5 秒以下。為確保您大多數使用者都達成這個目標,評估門檻是網頁載入的第 75 個百分位數,並按不同區隔的行動裝置和電腦裝置進行區隔。

良好 LCP 值不得超過 2.5 秒,低值超過 4.0 秒,且需要改善

哪些元素會列入考量?

根據目前在最大內容繪製 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 候選項目。系統只會考量元素的初始大小和可視區域中的位置。

這表示系統可能不會回報一開始算繪畫面外的圖片。這也代表一開始在可視區域算繪後,隨後向下而向下的元素,仍會回報在可視區域中的初始大小。

範例

以下列舉幾個熱門網站上出現最大內容繪製情況的範例:

cnn.com 最大的內容繪製時間軸

techcrunch.com 的大型內容繪製時間軸

在上述兩個時間軸中,最大的元素會在內容載入時變更。在第一個範例中,新內容會加入 DOM,並變更最大元素。在第二個範例中,版面配置變更和先前最大的內容會從可視區域中移除。

雖然延遲載入的內容通常比網頁上的內容還要大,但這不一定是如此。接下來的兩個例子是在頁面完全載入前發生的最大內容繪製情況。

instagram.com 上最大的內容繪製時間軸

google.com 的最大內容繪製時間軸

在第一個範例中,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 時間,並使用研究室資料細查和最佳化時間。

其他資源

網誌

偶爾會在用來評估指標的 API 中發現錯誤,有時也會發生指標本身定義。因此,有時您必須進行調整,內部報表和資訊主頁中都會顯示這類變更來改善或迴歸。

為協助您管理這種情況,這些指標的導入或定義都會在這份 CHANGELOG 中顯示。

如果您對這些指標有任何意見回饋,歡迎在 web-vitals-feedback Google 群組中提出。