Web Performance

延遲載入實際上會對你的最大內容繪製造成什麼影響

延遲載入很有用,但它不是通用的效能修補方式。對 LCP 來說,它可能有幫助、造成傷害,或完全沒有影響,取決於哪一項資源被延後。

The Wux Webtools Team The Wux Webtools Team 9 分鐘閱讀 AI輔助,人類審核
Illustration of a web performance timeline with a highlighted image request affecting LCP
目錄
  1. 延遲載入是一種排程決策,不是加速咒語
  2. 當你延遲載入圖片時,瀏覽器會做什麼
  3. 簡單規則:永遠不要延遲載入 LCP 候選元素
  4. 更正:使用實際的內部 URL
  5. 延遲載入何時可以改善 LCP
  6. LCP 圖片的更好模式
  7. 背景圖片需要額外小心
  8. JavaScript 延遲載入經常讓事情變得更糟
  9. LCP 不一定是圖片問題
  10. 如何測試延遲載入變更而不欺騙自己
  11. 多數網站適用的實務政策

延遲載入是一種排程決策,不是加速咒語

延遲載入常被描述為一種效能改善,這沒有錯,就像不把行李箱裝滿確實能減輕重量一樣。它之所以有幫助,是因為瀏覽器一開始要做的工作變少了。

這個差異對 Largest Contentful Paint 很重要,通常簡稱為 LCP。LCP 衡量的是視窗中最大的有意義元素何時被渲染。在許多頁面上,這個元素是一張 hero image。在其他頁面上,它可能是大型標題、poster image、產品照片,或一個內容區塊。

延遲載入會改變資源被請求的時間。它不會讓圖片解碼更快、伺服器回應更快,或字型更早渲染。如果你延遲載入錯誤的東西,尤其是最後成為 LCP 的元素,你等於是在告訴瀏覽器:先等一下,再去抓取它必須顯示、才能通過 Core Web Vitals 的那個東西。

這就是為什麼延遲載入既被過度使用,也經常沒有被充分理解。

當你延遲載入圖片時,瀏覽器會做什麼

原生圖片延遲載入通常會這樣加入:

<img src='hero.jpg' loading='lazy' alt='...'>

使用 loading='lazy' 時,瀏覽器可以延後抓取圖片,直到它認為這張圖片可能即將需要被使用。實務上,瀏覽器會使用與視窗的距離、網路條件、圖片尺寸,以及其他啟發式規則。確切規則屬於實作細節,而且可能改變。

使用 loading='eager',或在多數情況下沒有 lazy 屬性時,瀏覽器會把圖片視為一般載入流程的一部分。它仍然必須在 CSS、JavaScript、字型、圖片和其他請求之間做優先順序安排,但這張圖片會立刻被發現。

這表示延遲載入主要影響三個階段:

  • 發現: 瀏覽器注意到資源的時間。
  • 請求開始: 網路抓取開始的時間。
  • 渲染時機: 資源終於可以被解碼並繪製的時間。

對 LCP 來說,危險的是請求開始。如果 LCP 圖片請求開始得很晚,後面所有事情也都會跟著延後。

簡單規則:永遠不要延遲載入 LCP 候選元素

如果一張圖片在初始視窗中可見,而且很可能是最大的內容元素,就不要延遲載入它。

這包括:

  • hero images
  • 首屏以上的主要產品照片
  • 大型文章主圖
  • <img> 實作、類似背景的大型圖片
  • 當 poster 是主要視覺元素時的 video poster images

瀏覽器必須等到 LCP 圖片被請求、傳輸、解碼並繪製後,才能渲染它。延遲載入會在第一步之前加入不確定性。即使只是很小的延遲,也可能足以讓較慢連線上的 LCP 從可接受變成不佳。

常見的失敗模式如下:

  1. 伺服器送出 HTML。
  2. 瀏覽器解析到一張首屏以上的圖片。
  3. 圖片有 loading='lazy'
  4. 瀏覽器等待,因為延遲載入的啟發式規則認為它可以等。
  5. CSS 和 JavaScript 繼續載入。
  6. 圖片請求比應該開始的時間更晚才開始。
  7. 即使圖片檔案本身已經合理最佳化,LCP 仍然延遲。

這很令人沮喪,因為在程式碼審查中,頁面可能看起來很整潔。問題不只是檔案大小,而是優先順序。

如果你正在讀取實驗室工具輸出,並試著判斷 LCP 是否真的是問題,我們的指南 如何閱讀 Lighthouse 報告而不驚慌 刻意保持實用:在開始改程式碼之前,先區分現場資料、實驗室提示和修正方向。(注意:如果你的路由區分大小寫,請使用 CMS 中的確切 URL。)

更正:使用實際的內部 URL

正確的 Wux 文章 URL 是 如何閱讀 Lighthouse 報告而不驚慌。重點不變:在改變載入行為之前,先識別 LCP 元素。

延遲載入何時可以改善 LCP

當延遲載入讓非關鍵資源不擋在瀏覽器前面時,它可以間接改善 LCP。

想像一個產品頁,上方有一張 hero product image,首屏以下有一個包含十二張推薦圖片的 carousel。如果十三張圖片全部急切載入,瀏覽器可能會把頻寬和連線槽用在使用者還看不到的圖片上。在受限網路中,這可能會與 hero image、CSS 或字型檔案競爭。

延遲載入首屏以下的 carousel 圖片,可以幫助 LCP 圖片更早載入,因為初始頁面載入期間競爭的非關鍵請求變少了。

這才是延遲載入合理的效能使用情境:

  • 急切載入首屏以上的 LCP 候選元素
  • 延遲載入初始視窗以下的圖片
  • 避免用沉重的 scripts 很晚才注入重要圖片
  • 在 HTML 中保留圖片尺寸,以避免版面位移

延遲載入本身不是 LCP 最佳化。它是一種資源優先順序工具。當它保護關鍵路徑時,它才有幫助。

LCP 圖片的更好模式

對首屏以上的 LCP 圖片來說,目標是讓瀏覽器早點發現它、早點請求它,並在沒有版面不穩定的情況下渲染它。

穩健的基準做法如下:

<img
  src='/images/product-hero.avif'
  srcset='/images/product-hero-800.avif 800w, /images/product-hero-1400.avif 1400w'
  sizes='(max-width: 768px) 100vw, 720px'
  width='1400'
  height='900'
  loading='eager'
  fetchpriority='high'
  decoding='async'
  alt='Black hiking backpack with roll-top closure'
>

重要的部分不是裝飾:

  • loading='eager' 可避免延遲載入造成的等待。
  • fetchpriority='high' 告訴瀏覽器這張圖片很重要。
  • widthheight 預留空間並減少版面位移。
  • srcsetsizes 避免下載過大的圖片。
  • 現代格式在謹慎使用時可以減少傳輸時間。

如果你仍然對每個螢幕提供同一張大型 JPEG,圖片格式和響應式尺寸可能比 lazy-loading 屬性更重要。實用的決策樹可參考 AVIF 何時勝過 WebP,以及何時不會

背景圖片需要額外小心

CSS 背景圖片不會像一般 HTML 圖片那樣早被發現。瀏覽器必須先抓取並解析 CSS,才會知道它們存在。如果你的 LCP 元素是 CSS 背景圖片,你已經讓發現流程變得更困難。

這不表示背景圖片被禁止。它表示你應該有意識地使用它們。

對裝飾性圖片來說,CSS 背景沒問題。對有意義的 hero imagery 來說,<img><picture> 元素通常更好,因為它對 HTML parser 可見、支援 alt text,並且能與響應式圖片屬性良好搭配。

如果你必須為 LCP 圖片使用 CSS 背景,請考慮預先載入它:

<link rel='preload' as='image' href='/images/hero.avif'>

Preload 也不是魔法棒。預先載入太多圖片,會用另一種形式製造同樣的優先順序問題。把它用在真正重要的那一張圖片,而不是設計系統裡的每一張圖片。

JavaScript 延遲載入經常讓事情變得更糟

在原生延遲載入被廣泛支援之前,許多網站使用 JavaScript libraries,在頁面載入後或 intersection observer 觸發後,把 data-src 換進 src。有些網站現在仍然這麼做。

對長篇文章頁或大量圖片的 galleries 來說,這可能合理。對首屏以上內容來說,這是很差的選擇。

瀏覽器 preload scanner 很快,但如果圖片 URL 藏在自訂屬性裡,它就無法在 JavaScript 執行前請求那張圖片。如果你的 hero image 一開始是 data-src='hero.jpg',你就把發現流程延後到 script 下載、解析、執行和 framework hydration 之後。

這對 LCP 來說是很糟的取捨。把關鍵圖片 URL 放在真正的 HTML 裡。讓瀏覽器做它的工作。

LCP 不一定是圖片問題

在某些頁面上,LCP 元素是文字。在這種情況下,延遲載入圖片可能幾乎沒有直接影響。你的瓶頸可能是阻塞渲染的 CSS、緩慢的伺服器回應、client-side rendering,或 web fonts。

字型值得特別提起,因為它們經常是文字渲染延遲的隱藏原因。大型標題可能成為 LCP,而字型載入行為可能延遲或改變該標題繪製的時間。如果你的圖片調整沒有推動指標改善,請直接檢查 LCP 元素,而不是假設問題所在。我們關於 web fonts as a performance win 的文章涵蓋那些常常有效、但不刺激的修正:更少的 weights、現代格式、合理的 fallbacks。

如何測試延遲載入變更而不欺騙自己

不要只是坐在辦公室 Wi-Fi 上盯著頁面測試。你需要看到請求時機。

使用這個流程:

  1. 開啟 Chrome DevTools 並記錄 Performance trace。
  2. 啟用 network throttling,例如 Fast 4G 或 Slow 4G。
  3. 在停用快取的情況下重新載入頁面。
  4. 找到 LCP marker。
  5. 識別 LCP element。
  6. 在 Network panel 中,檢查該資源何時開始載入。

如果 LCP 資源開始得很晚,請問為什麼:

  • 它是否被延遲載入?
  • 它是否由 JavaScript 注入?
  • 它是否藏在 CSS 裡?
  • 它是否被其他圖片排擠而降低優先順序?
  • 伺服器回應是否很慢?

接著只做一項變更並重新測試。當團隊在同一次部署中同時改圖片格式、延遲載入、預先載入、JavaScript bundles 和 CDN 設定時,效能工作會變得混亂。你可能改善了頁面,但不會知道是哪一項變更真正有影響。

現場資料也很重要。實驗室工具有助於診斷,但 LCP 會因裝置、網路、視窗大小、快取狀態和地理位置而變動。可以的話,使用 real-user monitoring 或 Chrome User Experience Report 資料。

<!-- tool-cta:start -->

💡 試試這個: 透過 Image Compressor 處理你的 LCP 圖片,使其保持較小並優先載入,這樣就能不需要 lazy loading 也能快速渲染。

<!-- tool-cta:end -->

多數網站適用的實務政策

對多數 marketing sites、ecommerce pages、documentation sites 和 publisher pages 來說,這套政策已經足夠:

  • 首屏以上主要圖片:急切載入,並考慮高 fetch priority。
  • 首屏以下內容圖片:延遲載入。
  • Icons 和 tiny UI assets:通常不值得逐一思考。
  • CSS background hero:重新考慮改成 HTML image,或謹慎 preload。
  • JavaScript-injected hero image:如果可能,修正渲染架構。
  • Carousels:只急切載入第一個可見 slide;其餘延遲載入。

有些邊界案例。瀏覽器啟發式規則會改進。Frameworks 會加入自動圖片元件。有些 platforms 現在會避免延遲載入偵測到靠近視窗的圖片。即使如此,原則不變:關鍵資源應該早且明顯;非關鍵資源應該等待。

當延遲載入表達出這個差異時,它很有價值。當它把最重要的內容藏起來,直到頁面已經開始輸掉 LCP 競賽之後才讓瀏覽器看到時,它就有害。

常見問題

我是否應該在 hero image 上使用 loading='lazy'?
幾乎永遠不要。如果 hero image 在初始視窗中可見,它很可能會影響 LCP,應該急切載入。
延遲載入會改善 Core Web Vitals 嗎?
可以,但通常是間接改善。延遲載入首屏以下圖片可能減少早期網路競爭並幫助 LCP。延遲載入 LCP 圖片通常會讓 LCP 變差。
fetchpriority='high' 可以取代 eager loading 嗎?
不可以。把它作為重要圖片的額外提示。瀏覽器仍然需要早點發現資源,而且圖片不應該藏在延遲載入或 JavaScript 後面。
如果我的 LCP 元素是文字,而不是圖片呢?
那麼延遲載入圖片可能不會大幅改變 LCP。請檢查伺服器回應時間、阻塞渲染的 CSS、client-side rendering,以及 web font 行為。
每一張首屏以下圖片都應該延遲載入嗎?
通常是,尤其是在長頁面上。例外是那些很可能立刻進入視窗,或是版面關鍵互動所需的圖片。

來源與進一步閱讀

  1. web.dev: Browser-level image lazy loading for the web
  2. web.dev: Optimize Largest Contentful Paint
  3. MDN Web Docs: Lazy loading
  4. Chrome Developers: Optimize resource loading with the Fetch Priority API
關於作者
The Wux Webtools Team

最後更新:

繼續閱讀