在前端網站效能優化中,圖片處理是一個重要的部分,因為圖片通常是網頁中佔用大量頻寬和資源的元素之一。而關於圖片處理的實踐方法有多種,其中一種是將圖片壓縮
,這在本系列曾介紹過,請看 >>開箱14:前端圖片壓縮~Compressor.js範例應用,那本篇則是介紹原生就能處理圖片Lazy Loading(懶加載)的基礎方法
傳統上,當瀏覽者打開網頁時,網頁上的所有圖片和媒體資源都會立即加載,這可能會導致以下問題:網頁有較長的加載時間/浪費頻寬,而懶加載
(Lazy Loading)是一種網頁性能優化技術
,旨在改善網頁的加載速度和效能
。它主要用於圖片、視頻和其他媒體資源的加載,其核心思想是只在需要時才加載資源,而不是在頁面初次加載時全部載入
。
例如:網頁上有多張圖片,當用戶滾動頁面到該圖片位置,此時「需要」看到這張圖片時才載入資源
- 當頁面初次加載時,僅加載可見範圍內的內容,也就是位於視窗的視圖區域內的內容。
- 當用戶滾動頁面以瀏覽其他內容時,懶加載會動態加載進入視圖區域的圖片和媒體。
- 未進入視圖區域的資源將保持未加載的狀態,直到用戶滾動到它們的位置。
接著我們分別介紹前兩種方式
loading="lazy"
(如上圖)在範例中有100張的貓圖,真的只有在img標籤加上loading="lazy"
而己,就可以達到懶加載的效果!
// 用在圖片上
<img src="image.jpg" alt="..." loading="lazy" />
// 用在iframe上
<iframe src="video-player.html" title="..." loading="lazy"></iframe>
只要在HTML的<img>
標籤加上loading="lazy"
就行了?別懷疑!就是這麼簡單
快來看看套上去的效果 >>前往 Demo網址
我們使用 chrome檢查工具(F12) > Network > 下方選擇Img 來觀察,的確在使用者滑到某位置時,才依序載入圖片
IntersectionObserver API 是一個瀏覽器原生的JavaScript API,用於監視一個或多個元素與其祖先元素或視口之間的交集情況。它提供了一種有效的方式來檢測元素是否進入或離開可見區域,從而實現了許多常見的交互效果,如懶加載圖片、無限滾動、延遲加載廣告以及其他需要監視元素可見性的任務。
const observer = new IntersectionObserver(entries =>{
//doSomeThing
}, option);
observer.observe(需要監控的DOM)
threshold(閾值):單一數字或數組 EX:[0, 0.25, 0.5, 0.75, 1],決定了當目標元素的可見部分與根元素的交集比例達到指定閾值時,觸發回調函數。例如,如果設置threshold: 0.5,則表示當目標元素的一半進入可見區域時觸發回調。預設值為 0
root:根元素,即用於監視交集的容器元素。如果不指定,則默認為整個viewport(可見區域)。可以是任何有效的DOM元素。
rootMargin(根邊界):用於調整根元素的邊界框,以控制何時觸發交集事件。可以設置為一個字符串,指定四個邊界(上、右、下、左)的偏移量,也可以設置為一個包含四個值的數組。
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
// 目標元素進入可見區域時執行的操作
console.log('目標元素進入可見區域:', entry.target);
} else {
// 目標元素離開可見區域時執行的操作
console.log('目標元素離開可見區域:', entry.target);
}
});
});
const targetElement = document.querySelector('.target-element');
observer.observe(targetElement); // 開始監視目標元素
那我們就將原本loading="lazy"改為Intersection Observer API
前往 >> Demo
程式碼
html
<div class="image-container">
<img data-src="https://placekitten.com/403/403" width="403" height="403" alt="" />
...等其他張
</div>
javascript
const images = document.querySelectorAll('.image-container img');
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
console.log('entry.target',entry.target)
const img = entry.target;
const src = img.getAttribute('data-src');
// 將"data-src"的值設定為實際圖片的src,以加載圖片
if (src) {
img.src = src;
img.removeAttribute('data-src');
}
// 不再監視已經加載的圖片
observer.unobserve(img);
}
});
},{
threshold: 0.5,
});
// 開始監視每個圖片元素
images.forEach(img => {
observer.observe(img);
});
這樣就完成拉!
以下是我詢問chatGPT提供一些關於圖片處理的實踐方法:
圖片壓縮:
使用壓縮工具/套件來減小圖片文件的大小,減少頁面加載時間。選擇正確的圖片格式:
對於簡單的圖像或圖示,使用SVG或PNG格式。
對於照片和圖片,使用JPEG或WebP格式。圖片縮放:
調整圖片的寬度和高度,以符合其在網頁上的顯示大小,避免用CSS縮放圖片。
使用srcset和sizes屬性為不同螢幕大小提供適當大小的圖片。懶加載(Lazy Loading):
僅在用戶捲動到可視區域時加載圖片,以節省頻寬和加載時間。
使用HTML的loading="lazy"屬性來實現懶加載。使用圖片CDN:
使用內容傳遞網絡(CDN)來提供圖片,以減少伺服器負載和提高加載速度。圖片優化工作流:
使用自動化工具,如Webpack的image-webpack-loader的圖片壓縮插件,將圖片優化集成到建構過程中。緩存控制:
設定適當的緩存標頭,以確保瀏覽器可以有效地緩存圖片,減少重複下載。圖片的Responsive設計:
根據不同裝置和螢幕尺寸提供不同版本的圖片,以確保圖片在各種情況下都能正確呈現。綜合利用這些最佳實踐,可以幫助優化前端網站的性能,提供更快速的頁面加載和更好的用戶體驗。
那我們明天再見了~
參考資料
https://mingjun.lu/blog/lazy-loading-images-with-intersection-observer
https://web.dev/browser-level-image-lazy-loading/