舉例說明圖片懶載入的方案有哪些?

王铁柱6發表於2024-12-06

圖片懶載入的方案有很多,以下列舉幾種常見的方案,並分別解釋其原理和優缺點:

1. 基於 Intersection Observer API 的方案:

  • 原理: 利用 Intersection Observer API 監聽目標元素是否進入視口(viewport)。當目標元素進入視口時,觸發回撥函式,將圖片的真實 srcsrcset 屬性賦值,從而載入圖片。

  • 程式碼示例:

const images = document.querySelectorAll('img.lazy');

const observer = new IntersectionObserver((entries, observer) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const img = entry.target;
      img.src = img.dataset.src; // data-src 儲存圖片真實地址
      img.onload = () => {
        img.classList.remove('lazy'); // 可選:移除懶載入類名
      };
      observer.unobserve(img); // 停止觀察已載入的圖片
    }
  });
}, {
  rootMargin: '0px 0px 50px 0px' // 可選:提前載入,例如在元素距離視口 50px 時就開始載入
});

images.forEach(img => {
  observer.observe(img);
});

// HTML 結構示例
//<img class="lazy" data-src="image.jpg" src="placeholder.jpg" alt="My Image">
  • 優點: 效能優秀,相容性好,API 簡潔易用。
  • 缺點: 需要一定的 JavaScript 程式碼實現。

2. 基於 scroll 事件監聽的方案 (不推薦):

  • 原理: 監聽頁面的 scroll 事件,在事件回撥函式中計算每個圖片的位置,判斷其是否進入視口。如果進入視口,則載入圖片。

  • 缺點: 效能較差,scroll 事件觸發頻率很高,頻繁計算位置和判斷會導致頁面卡頓。不推薦使用。

3. 使用 <picture> 元素和 srcset 屬性結合 sizes 屬性:

  • 原理: 利用 <picture> 元素和 srcset 屬性,瀏覽器會根據當前視口大小和網路狀況選擇最合適的圖片載入。 sizes 屬性定義了不同視口寬度下圖片所佔的寬度,瀏覽器會根據這個資訊選擇合適的圖片源。

  • 程式碼示例:

<picture>
  <source media="(min-width: 800px)" srcset="large.jpg">
  <source media="(min-width: 400px)" srcset="medium.jpg">
  <img src="small.jpg" alt="My Image">
</picture>
  • 優點: 瀏覽器原生支援,無需 JavaScript 程式碼。可以根據不同的螢幕大小和網路狀況載入不同的圖片,提升使用者體驗。
  • 缺點: 不能實現真正的懶載入,只是根據視口大小選擇合適的圖片。

4. 使用 JavaScript 外掛:

  • 原理: 一些 JavaScript 外掛封裝了懶載入的邏輯,例如 lazysizeslozad.js 等。這些外掛通常使用 Intersection Observer API 或其他技術實現懶載入。

  • 優點: 使用方便,功能豐富,通常效能最佳化較好。

  • 缺點: 需要引入額外的 JavaScript 檔案。

最佳實踐:

  • 使用 Intersection Observer API 是目前最推薦的懶載入方案,效能好,相容性佳。
  • 使用佔點陣圖 (placeholder) 提升使用者體驗,例如使用低質量的模糊圖片或純色背景。
  • 結合 <picture> 元素和 srcset 屬性,可以根據不同的螢幕大小載入不同的圖片,進一步最佳化效能。

選擇哪種方案取決於專案的具體需求和技術棧。 對於大多數專案來說,使用 Intersection Observer API 或者一個輕量級的 JavaScript 外掛是最佳選擇。

相關文章