圖片懶載入的方案有很多,以下列舉幾種常見的方案,並分別解釋其原理和優缺點:
1. 基於 Intersection Observer API
的方案:
-
原理: 利用
Intersection Observer API
監聽目標元素是否進入視口(viewport)。當目標元素進入視口時,觸發回撥函式,將圖片的真實src
或srcset
屬性賦值,從而載入圖片。 -
程式碼示例:
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 外掛封裝了懶載入的邏輯,例如
lazysizes
、lozad.js
等。這些外掛通常使用Intersection Observer API
或其他技術實現懶載入。 -
優點: 使用方便,功能豐富,通常效能最佳化較好。
-
缺點: 需要引入額外的 JavaScript 檔案。
最佳實踐:
- 使用
Intersection Observer API
是目前最推薦的懶載入方案,效能好,相容性佳。 - 使用佔點陣圖 (
placeholder
) 提升使用者體驗,例如使用低質量的模糊圖片或純色背景。 - 結合
<picture>
元素和srcset
屬性,可以根據不同的螢幕大小載入不同的圖片,進一步最佳化效能。
選擇哪種方案取決於專案的具體需求和技術棧。 對於大多數專案來說,使用 Intersection Observer API
或者一個輕量級的 JavaScript 外掛是最佳選擇。