iT邦幫忙

2023 iThome 鐵人賽

DAY 16
0
Vue.js

Vue3歡樂套件箱耶系列 第 16

開箱16:圖片懶加載Lazy Loading範例應用

  • 分享至 

  • xImage
  •  

在前端網站效能優化中,圖片處理是一個重要的部分,因為圖片通常是網頁中佔用大量頻寬和資源的元素之一。而關於圖片處理的實踐方法有多種,其中一種是將圖片壓縮,這在本系列曾介紹過,請看 >>開箱14:前端圖片壓縮~Compressor.js範例應用,那本篇則是介紹原生就能處理圖片Lazy Loading(懶加載)的基礎方法

介紹 - 懶加載(Lazy Loading)

MDN網站介紹(Lazy Loading)

  • 懶加載(Lazy Loading)是什麼?

傳統上,當瀏覽者打開網頁時,網頁上的所有圖片和媒體資源都會立即加載,這可能會導致以下問題:網頁有較長的加載時間/浪費頻寬,而懶加載(Lazy Loading)是一種網頁性能優化技術旨在改善網頁的加載速度和效能。它主要用於圖片、視頻和其他媒體資源的加載,其核心思想是只在需要時才加載資源,而不是在頁面初次加載時全部載入

  • 那什麼時候是需要的時候?

例如:網頁上有多張圖片,當用戶滾動頁面到該圖片位置,此時「需要」看到這張圖片時才載入資源

  • 懶加載(Lazy Loading)的運作方式為何?
  • 當頁面初次加載時,僅加載可見範圍內的內容,也就是位於視窗的視圖區域內的內容。
  • 當用戶滾動頁面以瀏覽其他內容時,懶加載會動態加載進入視圖區域的圖片和媒體。
  • 未進入視圖區域的資源將保持未加載的狀態,直到用戶滾動到它們的位置。
  • 實現懶加載(Lazy Loading)目前的做法有?
  1. 使用 HTML屬性加上loading="lazy"
  2. 使用 Intersection Observer API(知道觀察到的元素何時進入或退出瀏覽器的視窗)
  3. 使用 第三方套件

接著我們分別介紹前兩種方式

- 使用 HTML屬性加上loading="lazy"

典型範例

https://ithelp.ithome.com.tw/upload/images/20231001/20142016SbqmRrUjSv.png
(如上圖)在範例中有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" 就行了?別懷疑!就是這麼簡單

loading屬性可以採用的值有
  1. lazy:用於延遲加載
  2. eager:用於立即加載,沒有任何延遲(這是預設值)

快來看看套上去的效果 >>前往 Demo網址

我們使用 chrome檢查工具(F12) > Network > 下方選擇Img 來觀察,的確在使用者滑到某位置時,才依序載入圖片

使用 Intersection Observer API

IntersectionObserver API 是一個瀏覽器原生的JavaScript API,用於監視一個或多個元素與其祖先元素或視口之間的交集情況。它提供了一種有效的方式來檢測元素是否進入或離開可見區域,從而實現了許多常見的交互效果,如懶加載圖片、無限滾動、延遲加載廣告以及其他需要監視元素可見性的任務。

MDN網站介紹(ntersection Observer API)

使用方式
const observer = new IntersectionObserver(entries =>{
      //doSomeThing
}, option);
observer.observe(需要監控的DOM)
option屬性可以採用的值有

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/


上一篇
開箱15:輕鬆套用訊息通知UI~Vue 3 Toastify範例應用
下一篇
開箱17:是不是跟我一樣困惑異步加載???defineAsyncComponent範例應用
系列文
Vue3歡樂套件箱耶30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言