最佳化最大內容繪製

逐步指南:如何分析 LCP 並找出需要改善的重要領域。

發布日期:2020 年 4 月 30 日

最大內容繪製 (LCP) 是三項網站使用體驗核心指標之一,代表網頁主要內容的載入速度。具體來說,LCP 會評估從使用者開始載入網頁,到可視區域中算繪最大圖片或文字區塊所需的時間。

為了提供良好的使用者體驗,網站應力求至少有 75% 的網頁瀏覽量,在 2.5 秒內完成 LCP

良好的 LCP 值為 2.5 秒以下,不良的值為 4.0 秒以上,介於兩者之間的值則需要改善
良好的 LCP 值應低於 2.5 秒。

許多因素都會影響瀏覽器載入及轉譯網頁的速度,而任何因素的延遲都可能對 LCP 造成重大影響。

只修改單一網頁的某個部分,通常無法有效改善 LCP。如要改善 LCP,您必須查看整個載入程序,並確保每個步驟都經過最佳化處理。

瞭解 LCP 指標

在改善 LCP 之前,開發人員應先瞭解是否有 LCP 問題,以及問題的嚴重程度。

您可以使用多種工具評估 LCP,但並非所有工具都以相同方式評估 LCP。如要瞭解實際使用者的 LCP,我們應觀察實際使用者體驗,而非 Lighthouse 或本機測試等實驗室工具顯示的結果。這些實驗室工具可提供豐富資訊,協助您瞭解並改善 LCP,但請注意,實驗室測試可能無法完全代表實際使用者體驗。

您可以透過在網站上安裝的實際使用者監控 (RUM) 工具,或使用 Chrome 使用者體驗報告 (CrUX),收集來自數百萬個網站的實際 Chrome 使用者匿名資料,以顯示以實際使用者為依據的 LCP 資料。

使用 Chrome 開發人員工具 CrUX LCP 資料

在 Chrome 開發人員工具的「效能」面板中,即時指標檢視畫面會在網頁或來源的 CrUX LCP 旁邊顯示本地 LCP 體驗。

Chrome 開發人員工具「效能」面板中的 LCP 本地和欄位
Chrome 開發人員工具「效能」面板中的「本地」和「欄位」LCP。

將欄位資料疊加至「效能」面板,即可評估網頁是否有任何實際使用者 LCP 問題,並調整本機環境設定,以便更有效地重現及偵錯這些問題。

使用 PageSpeed Insights CrUX LCP 資料

PageSpeed Insights 會在頂端的「探索真實使用者的體驗」部分提供 CrUX 資料。如要查看更詳細的研究資料,請前往標示為「診斷效能問題」的底部區段。如果網站有 CrUX 資料,請務必優先著重於實際使用者資料。

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

PageSpeed Insights 最多會顯示四種不同的 CrUX 資料:

  • 行動資料 (適用於這個網址)
  • 電腦版資料 (適用於這個網址)
  • 整個來源行動資料
  • 整個來源電腦資料

您可以在本節頂端和右上方的控制項中切換這些選項。如果網址的資料不足以在網址層級顯示,但有來源資料,PageSpeed Insights 一律會顯示來源資料。

當網址層級資料無法取得時,PageSpeed Insights 會改用來源層級資料
如果 PageSpeed Insights 沒有網址層級資料,就會顯示來源層級資料。

整個來源的 LCP 與個別網頁的 LCP 可能會有所差異,這取決於該網頁載入 LCP 的方式,以及該來源中其他網頁的 LCP 載入方式。這項指標也可能受到訪客前往這些網頁的方式影響。新使用者通常會造訪首頁,因此首頁通常會以「冷載入」方式載入,沒有任何快取內容,因此通常是網站上載入速度最慢的網頁。

查看 CrUX 資料的四個不同類別,有助於瞭解 LCP 問題是特定於這個網頁,還是更普遍的網站問題。同樣地,這項指標也能顯示哪些裝置類型有 LCP 問題。

使用 PageSpeed Insights CrUX 輔助指標

如要改善 LCP,您也應使用 首次顯示內容所需時間 (FCP)首次位元組時間 (TTFB) 時間,這兩項指標是良好的診斷指標,可提供有關 LCP 的寶貴洞察資料。

TTFB 是指訪客開始前往網頁 (例如點選連結) 到接收 HTML 文件的前幾個位元組之間的時間。TTFB 值過高,可能會導致 LCP 達到 2.5 秒的目標變得困難,甚至無法達標。

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 的建議。

除了改善商機,您還可以參考診斷資訊,進一步瞭解問題。「最大內容繪製元素」診斷工具會顯示 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。

發生這種情況的原因是,在這個網頁上,JavaScript 程式碼載入完成前,LCP 元素會處於隱藏狀態,然後才會一次顯示所有內容。

這個範例說明瞭您必須最佳化所有這些子部分,才能獲得最佳 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 元素會透過 JavaScript 程式庫延遲載入,該程式庫會隱藏 srcsrcset 屬性 (通常為 data-srcdata-srcset)。
  • LCP 元素需要 CSS 背景圖片。

在上述每個情況中,瀏覽器都必須先執行指令碼或套用樣式表,這通常會涉及等待網路要求完成,才能發現 LCP 資源並開始載入。這絕非最佳做法。

為避免不必要的資源載入延遲,LCP 資源應可從 HTML 來源中找到。如果資源僅由外部 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">

如果您認為 <img> 元素很可能是網頁的 LCP 元素,建議您在該元素上設定 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)。

圖片 CDN 特別實用,因為它不僅可縮短資源傳輸的距離,還能縮減資源大小,自動實作先前提供的所有縮減大小建議。

減少網路頻寬的爭用

即使您已縮減資源大小和傳輸距離,如果同時載入許多其他資源,資源仍可能需要很長的時間才能載入。這種問題稱為網路爭用

如果您為 LCP 資源指定了fetchpriority,並盡快開始載入,瀏覽器會盡力避免優先順序較低的資源與之競爭。不過,如果您載入許多具有高 fetchpriority 的資源,或是只是載入大量資源,就可能影響 LCP 資源的載入速度。

完全消除網路時間

如要縮短資源載入時間,最佳做法就是完全從程序中移除網路。如果您使用高效率的快取控制政策提供資源,則再次要求這些資源的訪客將從快取中取得資源,因此資源載入時間幾乎為零!

如果 LCP 資源是網路字型,除了縮減網路字型大小之外,您也應考慮是否需要在網路字型資源載入時阻擋轉譯作業。如果您設定的 font-display 值不是 autoblock,則文字會在載入期間一律顯示,且 LCP 不會因額外網路要求而遭到封鎖。

最後,如果 LCP 資源很小,建議您將資源內嵌為 資料網址,這樣一來也可以消除額外的網路要求。不過,使用資料網址有其限制,因為這樣就無法快取資源,且在某些情況下,由於額外的解碼成本,可能會導致顯示時間延遲。

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

這個步驟的目標是盡快提供初始 HTML。我們將這個步驟列在最後,因為開發人員通常無法完全控制這個步驟。不過,這也是最重要的步驟之一,因為它會直接影響後續的每個步驟。後端必須先傳送第一個位元組的內容,前端才會有所動作,因此任何可加快 TTFB 的做法,都會改善其他載入指標。

TTFB 速度緩慢的常見原因是訪客經過多次重新導向 (例如來自廣告或縮短連結) 才抵達網站。請盡量減少訪客必須等待的重新導向次數。

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

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

監控 JavaScript 中的 LCP 細目

如要取得上述所有 LCP 子項的時間資訊,您可以透過下列效能 API 組合,在 JavaScript 中取得:

在 JavaScript 中計算這些時間值的好處是,您可以將這些值傳送至分析供應商,或記錄至開發人員工具,以利進行偵錯和最佳化。

舉例來說,下圖擷取畫面使用 User Timing APIperformance.measure() 方法,在 Chrome 開發人員工具的「效能」面板中,將資料列新增至「時間」追蹤。

Chrome 開發人員工具中顯示的 LCP 子類別使用者時間測量值
「時間」軌跡會顯示 LCP 子類別的時間表。

Timings 軌道中的示意圖與NetworkMain thread 軌道搭配使用時特別實用,因為您可以一目瞭然地查看網頁在這些時間範圍內發生的其他事件。

除了在時間軸中以圖形呈現 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 細目。

摘要

LCP 相當複雜,其時間點可能會受到多項因素影響。不過,如果您認為 LCP 最佳化主要是為了提升 LCP 資源的載入速度,那麼這項最佳化作業就能大幅簡化。

整體來說,只要四個步驟就能完成 LCP 最佳化:

  1. 確保 LCP 資源盡早開始載入。
  2. 確保 LCP 元素可在資源載入完成後立即轉譯。
  3. 盡可能縮短 LCP 資源的載入時間,但不犧牲品質。
  4. 盡快提供初始 HTML 文件。

如果您能按照這些步驟為網頁進行最佳化,就能確保為使用者提供最佳載入體驗,實際的 LCP 分數也會反映這一點。