延遲載入圖片

由於圖片以 <img> 元素內嵌在 HTML 中,因此可能會顯示在網頁中 或 CSS 背景圖片本文將說明如何延遲載入這兩種圖片。

內嵌圖片

最常見的延遲載入候選圖片是用於 <img> 元素的圖片。 如果是內嵌圖片,我們有三種延遲載入選項 可與不同瀏覽器搭配使用,以達到最佳相容性:

使用瀏覽器層級的延遲載入

Chrome 和 Firefox 都支援使用 loading 屬性延遲載入功能。 這項屬性可以新增至 <img> 元素和 <iframe> 元素中。 lazy 值會指示瀏覽器立即載入可視區域中的圖片。 並在使用者捲動畫面附近時擷取其他圖片。

查看 MDN 的 loading 欄位 瀏覽器相容性 瀏覽器支援詳細資訊表格。 如果瀏覽器不支援延遲載入,系統會忽略該屬性 就會照常載入圖片

對大多數網站來說,在內嵌圖片中加入這項屬性有助於提升成效 載入圖片,讓使用者不會一直捲動畫面, 如果您擁有大量圖片,並想確保瀏覽器使用者不支援延遲載入功能, 您必須結合此方法與接下來說明的方法之一。

詳情請參閱網頁版瀏覽器層級的延遲載入功能

使用 Intersection Observer

為了對 <img> 元素執行 polyfill 延遲載入,我們會使用 JavaScript 來檢查這些元素是否位於 檢視區域如果是的話,其 src (有時是 srcset) 屬性 填入所需圖片內容的網址

如果您之前曾編寫延遲載入程式碼,那麼可能已完成工作 使用 scrollresize 等事件處理常式。雖然這個做法 新式瀏覽器提供的效能和 要更有效率地檢查元素可見度,方法是透過 Intersection Observer API

相較於依賴多項 因為您只需要註冊觀察器 而不是編寫繁瑣的元素可見度偵測程式碼。所有語言 這裡就是決定在元素顯示時的處理方式。 舉例來說,以下是延遲載入的 <img> 元素的基本標記模式:

<img class="lazy" src="placeholder-image.jpg" data-src="image-to-lazy-load-1x.jpg" data-srcset="image-to-lazy-load-2x.jpg 2x, image-to-lazy-load-1x.jpg 1x" alt="I'm an image!">

這項標記有三個相關部分,請著重在:

  1. class 屬性,也就是您選取元素時使用的屬性 JavaScript。
  2. src 屬性,會參照在 載入網頁的時間
  3. data-srcdata-srcset 屬性是預留位置屬性 。

現在讓我們看看如何在 JavaScript 中使用 Intersection Observer 來延遲載入 使用以下標記模式的圖片:

document.addEventListener("DOMContentLoaded", function() {
  var lazyImages = [].slice.call(document.querySelectorAll("img.lazy"));

  if ("IntersectionObserver" in window) {
    let lazyImageObserver = new IntersectionObserver(function(entries, observer) {
      entries.forEach(function(entry) {
        if (entry.isIntersecting) {
          let lazyImage = entry.target;
          lazyImage.src = lazyImage.dataset.src;
          lazyImage.srcset = lazyImage.dataset.srcset;
          lazyImage.classList.remove("lazy");
          lazyImageObserver.unobserve(lazyImage);
        }
      });
    });

    lazyImages.forEach(function(lazyImage) {
      lazyImageObserver.observe(lazyImage);
    });
  } else {
    // Possibly fall back to event handlers here
  }
});

在文件的 DOMContentLoaded 事件中,這個指令碼會向 DOM 查詢所有 類別為 lazy<img> 元素。如果有 Intersection Observer 建立新的觀察器,在 img.lazy 元素進入 檢視區域

Intersection Observer 適用於所有新式瀏覽器。 因此,將此函式做為 loading="lazy" 的 polyfill 可確保大多數訪客可以使用延遲載入。

CSS 中的圖片

儘管 <img> 標記是在網頁和圖片中使用圖片,是最常見的方式 也可以透過 CSS 叫用 background-image 資源 (以及其他資源) 之間的實用功能。瀏覽器層級的延遲載入不適用於 CSS 背景圖片。 因此,如果您有可延遲載入的背景圖片,請考慮其他方法。

不同於會載入的 <img> 元素 包括在 CSS 中載入圖片 推測。當文件和 CSS 物件 模型轉譯 樹 瀏覽器會先檢查 CSS 如何套用至文件 請求外部資源如果瀏覽器判定 CSS 規則 涉及外部資源的文件並不適用 瀏覽器未提出這項要求

您可以運用這種推測行為,延遲載入 CSS 中的圖片。 使用 JavaScript 判斷元素是否在可視區域中 隨後將該類別套用至該元素 套用樣式叫用 背景圖片如此一來,圖片會在必要時下載。 而不是在初始載入時啟動舉例來說,假設元素包含 大型主頁橫幅:

<div class="lazy-background">
  <h1>Here's a hero heading to get your attention!</h1>
  <p>Here's hero copy to convince you to buy a thing!</p>
  <a href="/buy-a-thing">Buy a thing!</a>
</div>

div.lazy-background 元素通常會包含主頁橫幅背景 部分 CSS 所叫用的圖片不過,在這個延遲載入範例中 透過 visiblediv.lazy-background 元素的 background-image 屬性 類別:

.lazy-background {
  background-image: url("hero-placeholder.jpg"); /* Placeholder image */
}

.lazy-background.visible {
  background-image: url("hero.jpg"); /* The final image */
}

接下來,您可使用 JavaScript 檢查元素是否位於可視區域 (使用 Intersection Observer!),並將 visible 類別新增至 當時的 div.lazy-background 元素,用於載入圖片:

document.addEventListener("DOMContentLoaded", function() {
  var lazyBackgrounds = [].slice.call(document.querySelectorAll(".lazy-background"));

  if ("IntersectionObserver" in window) {
    let lazyBackgroundObserver = new IntersectionObserver(function(entries, observer) {
      entries.forEach(function(entry) {
        if (entry.isIntersecting) {
          entry.target.classList.add("visible");
          lazyBackgroundObserver.unobserve(entry.target);
        }
      });
    });

    lazyBackgrounds.forEach(function(lazyBackground) {
      lazyBackgroundObserver.observe(lazyBackground);
    });
  }
});

對 Largest Contentful Paint (LCP) 的影響

延遲載入是一項絕佳的最佳化功能,可將圖片載入至實際需要的時間,減少啟動期間的整體數據用量和網路爭用情況。這樣可以縮短啟動時間,並減少圖片解碼所需時間,進而減少主執行緒的處理速度。

不過,如果您偏好使用延遲載入技術,則可能對網站的最大內容繪製 LCP 造成負面影響。建議您避免在啟動期間延遲載入可視區域內的圖片。

使用以 JavaScript 為基礎的延遲載入器時,建議您避免延遲載入可視區域圖片,因為這些解決方案通常會使用 data-srcdata-srcset 屬性做為 srcsrcset 屬性的預留位置。但問題在於瀏覽器預先載入掃描器在啟動期間找不到這些圖片,因而延遲載入這些圖片。

即使是使用瀏覽器層級的延遲載入來延遲載入可視區域圖片,也還是有辦法回溯觸發。將 loading="lazy" 套用至可視區域圖片時,該圖片會延遲顯示,直到瀏覽器確定圖片位於可視區域內,而這可能會影響網頁的 LCP。

不要在啟動期間延遲載入可視區域中顯示的圖片。這是一種模式,會對網站的 LCP 造成負面影響,進而影響使用者體驗。如需在啟動時盡快載入圖片,請不要延遲載入,讓圖片盡快載入!

延遲載入程式庫

建議您盡可能使用瀏覽器層級的延遲載入功能,但如果您後來發現無法繼續使用舊版瀏覽器 (例如大量使用舊版瀏覽器的使用者),可以使用下列程式庫延遲載入圖片:

  • lazysizes 是全功能延遲 載入延遲載入圖片和 iframe 的程式庫這個模型使用的模式 類似於這裡顯示的程式碼範例,程式碼會自動繫結至 <img> 元素的 lazyload 類別,需要您指定 data-src 和/或 data-srcset 屬性,會交換的內容 分別對應至 src 和/或 srcset 屬性。使用「十字路口」 Observer (可以 polyfill),且能使用多項 外掛程式 或是播放延遲影片進一步瞭解如何使用延遲尺寸
  • vanilla-lazyload 是 適用於延遲載入圖片、背景圖片、影片、iframe 和指令碼這個 API 運用 Intersection Observer,支援回應式圖片。 啟用瀏覽器層級的延遲載入。
  • lozad.js 是另一個輕量級 這個選項只能使用 Intersection Observer。它的高效能 但必須先填入折線,才能在舊版瀏覽器上使用
  • 如果您需要 React 專屬的延遲載入程式庫,請考慮 react-lazyload。期間 並未使用 Intersection Observer,但「確實」提供了熟悉的延遲方法 為習慣使用 React 開發應用程式的人載入映像檔。