最佳化最大內容繪製

這份逐步指南會說明如何細分 LCP,並找出需要改善的重要領域。

Largest Contentful Paint (LCP)Core Web Vitals 指標的其中一項,代表網頁主要內容的載入速度。具體來說,LCP 會評估使用者開始載入網頁,直到在可視區域中顯示最大圖片或文字區塊所需的時間。

為了提供良好的使用者體驗,網站應力求達到 2.5 秒或更短的 LCP 時間,至少佔 75% 的頁面造訪次數。

良好的 LCP 值應小於 2.5 秒、低於 4.0 秒、介於需求改善之間
良好的 LCP 值應在 2.5 秒內。

瀏覽器載入速度及網頁轉譯速度可能會因為各種因素而發生延遲,進而大幅影響 LCP。

快速修正網頁的某部分項目,並不會有效改善 LCP。為了改善 LCP,您必須查看整個載入程序,並確保過程中的每個步驟都最佳化。

瞭解 LCP 指標

最佳化 LCP 前,開發人員應想要瞭解是否有 LCP 問題以及這類問題的嚴重程度。

LCP 可透過許多工具評估,且並非所有 LCP 都會以同樣的方式進行評估。為了瞭解實際使用者的 LCP,我們應關注實際使用者的體驗,而非使用 Lighthouse 或本機測試之類的實驗室式工具。這些研究室型工具可提供豐富的資訊,說明並協助您改善 LCP。不過請注意,光是研究室測試,不見得能完全反映實際使用者體驗。

如顯示以真實使用者的 LCP 資料,如透過網站上安裝的即時使用者監控工具 (RUM) 工具,或使用 Chrome 使用者體驗報告 (CrUX) 的資料即可得知,該報告 (CrUX) 會針對數百萬個網站收集真實 Chrome 使用者的匿名資料。

使用 PageSpeed Insights CrUX LCP 資料

您可以透過 PageSpeed Insights 存取 CrUX 資料位於頂端的「瞭解實際使用者體驗」部分。如需更詳細的研究室資料,請查看底部的「診斷效能問題」部分。如果網站有 CrUX 資料,請一律先考量實際的使用者資料。

PageSpeed Insights 中顯示的 CrUX 資料
PageSpeed Insights 中顯示的 CrUX 資料。

PageSpeed Insights 最多可顯示四項不同的 CrUX 資料:

  • 這個網址行動資料
  • 這個網址電腦版資料
  • 整個來源行動資料
  • 整個來源電腦資料

您可以在這個部分頂端和右上方的控制項中切換這些設定。如果網址沒有足夠資料 (可在網址層級顯示),但其中確實有來源的資料,PageSpeed Insights 一律會顯示來源資料。

PageSpeed Insight 捨棄網址層級資料的來源層級資料
如果 PageSpeed Insights 沒有網址層級資料,就會顯示 來源層級資料

整個來源的 LCP 可能與個別網頁的 LCP 非常不同,這取決於該網頁的 LCP 載入方式,以及與該來源的其他網頁相比。訪客瀏覽這些網頁的方式也會影響排名。首頁往往會被新使用者瀏覽,因此通常載入「冷」、沒有快取內容,因此通常是網站上速度最慢的網頁。

查看 4 種不同類別的 CrUX 資料,有助於瞭解 LCP 問題是網頁本身,還是通用的網站問題。同樣地,這項工具也能顯示哪些裝置類型有 LCP 問題。

使用 PageSpeed Insights CrUX 補充指標

如果要最佳化 LCP,也應採用「首次顯示內容所需時間 (FCP)」和「第一個位元組時間 (TTFB)」時間,這兩項實用的診斷指標,有助於深入瞭解 LCP。

TTFB 是指訪客開始瀏覽頁面 (例如點擊連結),直到收到 HTML 文件的第一個位元組為止。TTFB 較高時,可能會導致 2.5 秒的 LCP 面臨挑戰,甚至不可能。

TTFB 偏高的原因,可能是多個伺服器重新導向、離最近的網站伺服器較遠、網路狀況不理想,或是因為查詢參數無法使用快取內容所致。

頁面開始轉譯後,畫面會先套用初始所需時間 (例如背景顏色),之後可能會出現一些內容 (例如網站標題)。初始內容的外觀是由 FCP 評估。FCP 和其他指標之間的差異非常有意義。

TTFB 和 FCP 之間的差距很大,可能表示瀏覽器需要下載大量會妨礙顯示的資產。這也代表其必須完成大量工作才能轉譯任何有意義的內容,這是一種經典的象徵,也就是高度依賴用戶端轉譯的網站。

FCP 和 LCP 之間的差距很大,表示瀏覽器無法立即取得 LCP 資源做為優先處理順序 (例如由 JavaScript 管理,而非提供初始 HTML 中之文字或圖片),或者瀏覽器在顯示 LCP 內容之前,會先完成其他工作。

使用 PageSpeed Insights Lighthouse 資料

PageSpeed Insights 的 Lighthouse 部分提供了改善 LCP 的指南,但請先檢查你提供的 LCP 是否與 CrUX 提供的實際使用者資料一致。如果 Lighthouse 和 CrUX 不同意,CrUX 可能可以提供更準確的使用者體驗。採取行動之前,請先確認你的 CrUX 資料是網頁,而非完整來源。

如果 Lighthouse 和 CrUX 皆顯示需要改善的 LCP 值,Lighthouse 區段提供的指引能幫助您改善 LCP。使用 LCP 篩選器即可只顯示與 LCP 相關的稽核項目,方法如下:

Lighthouse LCP 商機和診斷
Lighthouse 診斷和建議,協助改善 LCP。

除了改善的「商機」部分,您還可以查看「診斷」資訊,提供更多有助於診斷問題的資訊。Largest Contentful Paint 元素診斷工具會顯示檔案,方便您分析 LCP 的各種時機:

Lighthouse LCP 階段
Lighthouse 提供 LCP 元素的詳細資料。

接下來,我們會深入探討這些子部分。

LCP 詳細資料

如果 PageSpeed Insights 無法讓您瞭解如何改善這項指標,進行 LCP 最佳化作業可能會較為複雜。如果是複雜的工作,通常會把工作拆成較小、更易於管理的工作,並分別處理。

本節將說明如何將 LCP 細分為最關鍵的子部分,然後針對各個部分提出具體的建議和最佳做法。

大多數的網頁載入通常都會包含一些網路要求,但為了找出改善 LCP 的機會,建議您先從以下兩個面向開始:

  1. 初始 HTML 文件
  2. LCP 資源 (如適用)

雖然網頁上的其他要求可能會影響 LCP,但這兩個要求 (特別是 LCP 資源開始和結束的時間) 都會顯示您的網頁是否針對 LCP 最佳化。

如要找出 LCP 資源,可以使用開發人員工具 (例如上述的 PageSpeed Insights、Chrome 開發人員工具WebPageTest) 判斷 LCP 元素。接下來,您可以在頁面所載入的所有資源的聯播網刊登序列中,比對由元素載入的網址 (同樣視情況而定)。

舉例來說,下列圖表顯示在一般網頁載入下,網路刊登序列圖表上醒目顯示的資源,其中 LCP 元素需要提出圖片要求才能顯示。

醒目顯示 HTML 和 LCP 資源的網路刊登序列
以圖表呈現 網頁的 HTML 以及 LCP 所需的資源

為了讓網頁發揮最佳成效,您希望 LCP 資源要求盡快開始載入,並希望 LCP 資源在 LCP 資源載入完畢後盡快顯示。為了協助視覺化呈現特定網頁是否遵循這項原則,您可以將 LCP 總時間細分為下列子部分:

首次位元組時間 (TTFB)
從使用者開始載入網頁到瀏覽器之間的時間 接收 HTML 文件回應的第一個位元組。
資源載入延遲
從 TTFB 到瀏覽器開始載入 LCP 資源之間的時間。如果 不需要載入資源即可轉譯 LCP 元素 (例如 元素是文字節點,以系統字型顯示),這次值為 0。
資源載入時長
載入 LCP 資源本身所需的時間。如果 LCP 元素不需要載入資源即可算繪,但這次值為 0。
元素轉譯延遲時間
從 LCP 資源完成載入到 LCP 元素之間的時間長度 算繪的所有結果

每個網頁的 LCP 都包含以下四個子類別。兩者沒有差異或重疊 而且加總起來就是整個 LCP 時間

LCP 顯示四個子類別的細目
相同的瀑布圖,圖中有四個 LCP 子類別 順帶一提

每個網頁的 LCP 值都可以細分為這四個子部分。兩者之間沒有重疊或間隔。這些影格合計會加總到所有 LCP 時間。

最佳化 LCP 時,建議您逐一最佳化這些子部分。不過請注意,您必須最佳化所有這些項目。在某些情況下,套用到某個部分的最佳化功能並不能改善 LCP,只會將省下的時間轉移至其他部分。

舉例來說,在先前的網路刊登序列中,如果您透過進一步壓縮圖片來縮減檔案大小,或是改用更好的格式 (例如 AVIF 或 WebP),可縮短資源載入時間,但實際上不會改善 LCP,因為時間只會轉移至「元素轉譯延遲時間」子部分:

前面提到的 LCP 細目,其中資源載入時間子類別縮短的情況,但整體 LCP 時間仍維持不變。
縮短資源載入時間會增加元素的轉譯延遲時間,而不會減少 LCP。

發生這種情況的原因是,網頁上的 LCP 元素會一直隱藏,直到 JavaScript 程式碼載入完成,接著所有內容都會立即顯示。

這個例子說明您需要在哪些方面調整出最佳狀態,才能達到最佳的 LCP 效果。

最佳子部分時間

為了最佳化 LCP 的各個子部分,請務必瞭解這些子部分的理想細目為何,這樣才能充分改善網頁。

其中四個子部分有「delay」這個字。也就是說,您希望這些時間盡可能接近零。其他兩個部分是網路要求,由於其本質相當耗時。

LCP 子部分 LCP 百分比
第一位元組時間 約 40%
資源載入延遲 <10%
資源載入時長 約 40%
元素轉譯延遲時間 <10%
總計 100%

請注意,這些時間細目是準則,而非嚴格的規則。如果網頁上的 LCP 時間持續在 2.5 秒內,相對比例其實並不重要。但如果您在「延遲」期間就會難以持續達成 2.5 秒的目標

以下提供 LCP 時間細分的好方法:

  • 絕大部分 LCP 時間都應花在載入 HTML 文件和 LCP 來源。
  • 在 LCP 之前的任何時候,如果這兩項資源「無法」載入,就有改進空間

如何改善各個層面

現在您已經瞭解每個 LCP 子部分在經過最佳化調整後應該如何進行細分,接下來就可以開始最佳化自己的網頁。

接下來的四節將針對各個環節提供最佳化的建議和最佳做法。系統會按照順序,由最有可能影響成效的最佳化著手。

1. 消除資源載入延遲

此步驟的目標是確保 LCP 資源盡快開始載入。理論上來說,資源最早可以立即開始載入 TTFB 之後,但實際上,瀏覽器實際上要過一段時間才會開始載入資源。

原則上,您的 LCP 資源應與該網頁載入的第一個資源同時開始載入。此外,如要換個角度,如果 LCP 資源晚於第一項資源開始載入,則有改善空間。

網路瀑布圖,顯示從第一項資源開始之後開始的 LCP 資源,當中顯示改善機會
在這個頁面中,LCP 資源會在樣式結束後順利開始載入 會先載入的工作表。這裡還有改善空間。

一般而言,影響 LCP 資源的載入速度會受以下兩個因素影響:

  • 找到資源時。
  • 資源的優先順序。

找到資源時進行最佳化

為了確保 LCP 資源能盡快開始載入,請務必讓瀏覽器的預先載入掃描器在初始 HTML 文件回應中發現資源。例如,在下列情況中,瀏覽器可以掃描 HTML 文件回應,找出 LCP 資源:

  • LCP 元素為 <img> 元素,且其 srcsrcset 屬性出現在初始 HTML 標記中。
  • LCP 元素需要使用 CSS 背景圖片,但該圖片是透過 HTML 標記中的 <link rel="preload"> (或使用 Link 標頭) 預先載入。
  • LCP 元素是需要顯示網站字型的文字節點,且系統會使用 HTML 標記中的 <link rel="preload"> (或使用 Link 標頭) 載入字型。

以下列舉幾個例子,說明系統無法在掃描 HTML 文件回應時找到 LCP 資源:

  • LCP 元素是一種使用 JavaScript 動態新增至網頁的 <img>
  • LCP 元素會延遲載入,並含有隱藏其 srcsrcset 屬性的 JavaScript 程式庫 (通常是 data-srcdata-srcset)。
  • LCP 元素需要 CSS 背景圖片。

在這些情況下,瀏覽器都必須執行指令碼或套用樣式表 (通常需要等待網路要求完成),才能發現 LCP 資源並開始載入。並非最佳成效。

為避免不必要的資源載入延遲,Google 可在 HTML 原始碼中找到您的 LCP 資源。如果只從外部 CSS 或 JavaScript 檔案參照資源,則應以較高的「擷取優先順序」預先載入 LCP 資源,例如:

<!-- Load the stylesheet that will reference the LCP image. -->
<link rel="stylesheet" href="/path/to/styles.css">

<!-- Preload the LCP image with a high fetchpriority so it starts loading with the stylesheet. -->
<link rel="preload" fetchpriority="high" as="image" href="/path/to/hero-image.webp" type="image/webp">

將指定資源的優先順序最佳化

即使 LCP 資源可從 HTML 標記找到,但「仍然」可能無法像第一項資源一樣提早開始載入。如果瀏覽器預先載入掃描器的優先順序經驗法則無法辨識資源重要,或判定其他資源較為重要,可能就會發生上述情況。

舉例來說,如果您在 <img> 元素上設定 loading="lazy",即可使用 HTML 延遲 LCP 圖片。使用延遲載入表示,等到版面配置確認圖片位於可視區域後,才會載入資源,因此可能之後才開始載入。

即使沒有延遲載入,瀏覽器一開始也不會以最高優先順序載入圖片,因為這些圖片不會阻礙轉譯的資源。您可以使用 fetchpriority 屬性,提示瀏覽器應該是最重要的資源,取得優先順序較高的資源:

<img fetchpriority="high" src="/path/to/hero-image.webp">

如果你認為網頁 LCP 元素很有可能是網頁的 LCP 元素,建議在 <img> 元素上設定 fetchpriority="high"。不過,若將超過一或兩張圖片設為高優先順序,優先順序設定就無法降低 LCP。

您也可以降低文件回應初期,但因樣式而看不到的圖片 (例如啟動時未顯示的輪轉介面投影片中的圖片),降低優先順序。

<img fetchpriority="low" src="/path/to/carousel-slide-3.webp">

將某些資源的優先順序降為最低,能讓更多頻寬佔用更多頻寬,但請小心謹慎。請一律在開發人員工具中檢查資源優先順序,並使用研究室和現場工具測試變更。

最佳化 LCP 資源優先順序和探索時間後,網路刊登序列應如下所示 (其中 LCP 資源會與第一個資源同時開始):

顯示 LCP 資源與第一個資源採用相同時間的網路刊登序列圖表
LCP 資源現在和樣式表會同時開始載入。

2. 排除元素轉譯延遲

這個步驟的目標是確保 LCP 元素在資源載入完畢後「立即」顯示,無論發生情況為何。

LCP 元素「無法」在資源載入完成後立即顯示,主要原因是轉譯作業因其他原因而遭到封鎖

  • 由於 <head> 中的樣式表或同步指令碼仍在載入,因此系統無法轉譯整個網頁。
  • LCP 資源已載入完成,但 LCP 元素尚未加入 DOM (正在等待載入某些 JavaScript 程式碼)。
  • 其他程式碼隱藏了元素,例如 A/B 測試程式庫仍在決定使用者應進入的實驗。
  • 主執行緒因長時間工作而遭到封鎖,轉譯工作需等待這些長時間工作完成。

以下各節將說明如何解決造成非必要元素轉譯延遲的最常見原因。

減少或內嵌禁止轉譯的樣式表

從 HTML 標記載入的樣式表,會讓所有後續內容無法顯示,這是很好的選擇,因為您通常不想轉譯未經樣式的 HTML。不過,如果樣式表太大,載入時間遠比 LCP 資源長,則會在資源完成載入之後,防止 LCP 元素算繪,如以下範例所示:

網路瀑布圖,顯示大型 CSS 檔案造成 LCP 元素算繪,因載入時間超過 LCP 資源而遭到封鎖
圖片和樣式表會同時開始載入,但必須等到樣式表就緒後才能算繪圖片。

如要解決這個問題,您可以採用下列任一做法:

  • 將樣式表內嵌到 HTML 中,以避免額外的網路要求;或
  • 縮減樣式表的大小

一般來說,我們並不建議在樣式表中添加小型檔案的情況下,才建議嵌入樣式表,因為 HTML 中的內嵌內容無法透過後續載入的網頁進行快取。如果樣式表單的載入時間比 LCP 資源更長,就不太可能適合內嵌。

在大多數情況下,要確保樣式表不會阻礙 LCP 元素轉譯,最好的方式就是縮減其大小,使其小於 LCP 資源。以免造成大多數造訪的瓶頸。

以下是有助於縮減樣式表大小的建議:

延遲或內嵌禁止轉譯的 JavaScript

在網頁的 <head> 中加入同步指令碼 (不含 asyncdefer 屬性的指令碼) 幾乎不見得需要,這麼做幾乎對成效造成負面影響。

如果 JavaScript 程式碼必須在網頁載入時盡早執行,建議您以內嵌的方式內嵌,以免轉譯程序因為出現其他網路要求而延遲。不過,和樣式表一樣,建議您只有在內嵌指令碼太小的情況下才插入程式碼。

錯誤做法
<head>
  <script src="/path/to/main.js"></script>
</head>
正確做法
<head>
  <script>
    // Inline script contents directly in the HTML.
    // IMPORTANT: only do this for very small scripts.
  </script>
</head>

使用伺服器端轉譯

伺服器端轉譯 (SSR) 是指在伺服器上執行用戶端應用程式邏輯,並使用完整 HTML 標記回應 HTML 文件要求的程序。

就最佳化 LCP 而言,SSR 主要有兩項優點:

  • 使用者可以從 HTML 來源找到圖片資源 (如前文步驟 1 所述)。
  • 網頁內容不需要再完成 JavaScript 要求就能顯示。

SSR 的主要缺點是需要額外的伺服器處理時間,可能會拖慢 TTFB。權衡取捨通常值得,因為伺服器處理時間完全由您掌控,但使用者的網路和裝置功能則並非如此。

與 SSR 的類似選項稱為「靜態網站產生 (SSG)」或「預先轉譯」。透過這個程序,您可以在建構步驟 (而非隨選) 中產生 HTML 網頁。如果您的架構可以進行預先算繪,那麼效能通常會是更好的選擇。

分散長時間執行的工作

即使您已遵循上述的建議,且您的 JavaScript 程式碼並未阻擋轉譯,也不是負責轉譯元素,還是可能會延遲 LCP。

這種情況最常見的原因是網頁載入大型 JavaScript 檔案,而這類檔案必須在瀏覽器的主執行緒上剖析及執行。這表示,即使圖片資源已完整下載,可能還是要等到不相關的指令碼執行完畢之後,才能顯示這些資源。

目前,所有瀏覽器都會在主執行緒上轉譯圖片,也就是說,任何妨礙主執行緒的內容,都可能導致不必要的元素轉譯延遲

3. 縮短資源載入時間

這個步驟的目標是減少透過網路將資源位元組轉移到使用者裝置的時間。一般而言,使用者可採用下列三種方式:

  • 縮減資源大小。
  • 減少資源行進的距離。
  • 減少網路頻寬的爭用情形。
  • 完全節省網路時間。

縮減資源大小

網頁的 LCP 資源 (如果有的話) 可以是圖片或網路字型。下列指南詳細說明如何縮減兩者的大小:

縮短資源移動的距離

除了縮減資源大小,您也可以盡可能讓伺服器靠近使用者所在的區域,藉此縮短載入時間。最佳做法是使用內容傳遞網路 (CDN)。

Image CDN 特別有用,原因是這類 CDN 不僅可縮短資源移動所需的距離,而且通常會縮減資源大小,自動導入稍早提供的所有縮減建議大小。

減少網路頻寬的爭用情形

即使您已縮減資源大小及所需的移動距離,但如果您同時載入許多其他資源,系統仍可能花費較長的時間載入資源。這個問題稱為「網路爭用情況」

如果您已為 LCP 資源提供較高的 fetchpriority,並盡快開始載入該資源,瀏覽器會盡可能防止優先順序較低的資源互相競爭。不過,如果載入許多具有較高 fetchpriority 的資源,或一般只是載入大量資源,可能會影響 LCP 資源載入的速度。

完全省去網路時間

縮短資源載入時間的最佳方式,就是完全將網路從處理程序中刪除。如果您為資源設定了高效率的快取控制政策,第二次要求這些資源的訪客會從快取提供資源,將資源載入時間縮短為零!

如果 LCP 資源是網路字型,且除了縮減網頁字型大小以外,您也應考慮是否要禁止在網路字型資源載入時顯示轉譯結果。如果將 font-display 值設為 autoblock 以外的值,則文字會在載入期間一律顯示,且不會因其他網路要求封鎖 LCP。

最後,如果您的 LCP 資源較小,不妨以「資料網址」的形式內嵌資源,這樣也能刪除額外的網路要求。不過,使用資料網址時會有特別的注意事項,因為系統無法快取資源。而且在某些情況下,額外解碼費用可能會使轉譯延遲更久。

4. 縮短第一個位元組的時間

這個步驟的目標是盡快放送初始 HTML。這個步驟最後列出的是最後,因為開發人員通常擁有最低限度的控制權。不過,這也是最重要的步驟,因為這會直接影響之後完成的每一個步驟。除非後端傳送其中第一個位元組的內容,否則前端沒有任何作用,因此加快 TTFB 前所採取的做法,也會改善所有其他載入指標。

訪客速度太慢 (例如透過廣告或短連結) 連上多次重新導向,會導致 TTFB 速度過慢。請務必盡量減少訪客必須等待的重新導向次數。

另一個常見原因則是無法使用 CDN 邊緣伺服器中的快取內容,而且所有要求都必須一路導向原始伺服器。如果訪客使用不重複的網址參數來執行分析,即使訪客不會產生不同的網頁,也可能發生這種情況。

如需 TTFB 最佳化的具體指南,請參閱 TFB 最佳化指南

監控 JavaScript 中的 LCP 細目

上述所有 LCP 子部分的時間資訊可透過 JavaScript 組合,讓您透過下列效能 API 使用:

在 JavaScript 中計算這些時間值的優點,是將值傳送給分析服務供應商或記錄到開發人員工具,以利偵錯及最佳化。

舉例來說,下列螢幕截圖使用 User Timing APIperformance.measure() 方法,在 Chrome 開發人員工具效能面板中的 Timings 追蹤中加入長條。

Chrome 開發人員工具中以視覺化方式呈現 LCP 子類別的使用者載入時間測量指標
「時間」軌跡顯示 LCP 子類別的時間軸。

當您一併查看「網路」和「主要執行緒」追蹤期間,系統會特別顯示「時機」測試群組中的視覺化圖表,因為您可以快速瞭解在這個時間範圍內還有哪些活動。

除了以視覺化方式呈現時間軌中的 LCP 子部分,您也可以使用 JavaScript 計算 LCP 總時間中每個子部分的百分比。掌握這項資訊,您就可以判斷網頁是否符合前述建議百分比細目

這張螢幕截圖顯示一個範例,記錄每個 LCP 子部分的總時間,以及該 LCP 總使用時間在控制台中的記錄。

LCP 子類別時間及 LCP 百分比都會顯示在控制台上
LCP 子類別時間和百分比

這兩種圖表都是使用下列程式碼建立:

const LCP_SUB_PARTS = [
  'Time to first byte',
  'Resource load delay',
  'Resource load duration',
  'Element render delay',
];

new PerformanceObserver((list) => {
  const lcpEntry = list.getEntries().at(-1);
  const navEntry = performance.getEntriesByType('navigation')[0];
  const lcpResEntry = performance
    .getEntriesByType('resource')
    .filter((e) => e.name === lcpEntry.url)[0];

  // Ignore LCP entries that aren't images to reduce DevTools noise.
  // Comment this line out if you want to include text entries.
  if (!lcpEntry.url) return;

  // Compute the start and end times of each LCP sub-part.
  // WARNING! If your LCP resource is loaded cross-origin, make sure to add
  // the `Timing-Allow-Origin` (TAO) header to get the most accurate results.
  const ttfb = navEntry.responseStart;
  const lcpRequestStart = Math.max(
    ttfb,
    // Prefer `requestStart` (if TOA is set), otherwise use `startTime`.
    lcpResEntry ? lcpResEntry.requestStart || lcpResEntry.startTime : 0
  );
  const lcpResponseEnd = Math.max(
    lcpRequestStart,
    lcpResEntry ? lcpResEntry.responseEnd : 0
  );
  const lcpRenderTime = Math.max(
    lcpResponseEnd,
    // Use LCP startTime (the final LCP time) because there are sometimes
    // slight differences between loadTime/renderTime and startTime
    // due to rounding precision.
    lcpEntry ? lcpEntry.startTime : 0
  );

  // Clear previous measures before making new ones.
  // Note: due to a bug, this doesn't work in Chrome DevTools.
  LCP_SUB_PARTS.forEach((part) => performance.clearMeasures(part));

  // Create measures for each LCP sub-part for easier
  // visualization in the Chrome DevTools Performance panel.
  const lcpSubPartMeasures = [
    performance.measure(LCP_SUB_PARTS[0], {
      start: 0,
      end: ttfb,
    }),
    performance.measure(LCP_SUB_PARTS[1], {
      start: ttfb,
      end: lcpRequestStart,
    }),
    performance.measure(LCP_SUB_PARTS[2], {
      start: lcpRequestStart,
      end: lcpResponseEnd,
    }),
    performance.measure(LCP_SUB_PARTS[3], {
      start: lcpResponseEnd,
      end: lcpRenderTime,
    }),
  ];

  // Log helpful debug information to the console.
  console.log('LCP value: ', lcpRenderTime);
  console.log('LCP element: ', lcpEntry.element, lcpEntry.url);
  console.table(
    lcpSubPartMeasures.map((measure) => ({
      'LCP sub-part': measure.name,
      'Time (ms)': measure.duration,
      '% of LCP': `${
        Math.round((1000 * measure.duration) / lcpRenderTime) / 10
      }%`,
    }))
  );
}).observe({type: 'largest-contentful-paint', buffered: true});

您可以將此程式碼直接用於本機偵錯,也可以修改程式碼將這些資料傳送給分析供應商,以便進一步瞭解實際使用者在網頁上的 LCP 細目。

使用 Web Vitals 擴充功能監控 LCP 細目

網站體驗指標擴充功能記錄 LCP 時間、LCP 元素以及控制台中的這四個子部分,方便你查看這項細目。

Web Vitals 擴充功能的主控台記錄螢幕截圖,顯示 LCP 子部分的時間
網頁版「控制台」面板 Vitals 擴充功能會顯示 LCP 細目。

摘要

LCP 很複雜,時間會受到許多因素影響。不過,若您認為最佳化 LCP 的重點在於改善 LCP 資源的負載,可能會大幅簡化 LCP。

大致來說,最佳化 LCP 最佳化可分為四個步驟:

  1. 確保 LCP 資源盡快開始載入。
  2. 確保 LCP 元素可在資源完成載入後立即算繪。
  3. 在不影響品質的情況下,盡可能縮短 LCP 資源的載入時間。
  4. 請盡快提供初始 HTML 文件。

如果能在網頁上完成上述步驟,則應該確定網站能為使用者提供最佳載入體驗,也應該能反映實際的 LCP 分數。