網頁圖片延遲載入方法 (Lazy loading)
網頁開發網頁載入時,最耗費流量的資源大概就是圖片了。為了節省流量的浪費,除了將圖片在可接受畫質的狀況下,盡可能的將檔案大小進行壓縮之外,另一個實用技巧就是延遲載入 (Lazy loading)。
有關圖片壓縮方法,可以參考部落格中的另外一篇文章,下方為文章連結。
延遲載入解決了什麼問題呢?
我們假設有一個使用了 50 張圖片的網頁,正常情況下,當使用者進入網頁後,瀏覽器會等這 50 張圖片都載入完成才會顯示畫面,試想在不捲動右邊卷軸的狀況下,我們第一眼從畫面中大概只能看到最前面的 4 到 5 張圖而已,可是卻要等全部 50 張圖都載入完成才能觀看。 再假設一張圖片只要 500KB 就好,這樣首次進入網頁就要載入高達 25MB 的圖片,而且還要加上其他 CSS 及 JavaScript 等必要檔案,這明顯是很浪費流量的事情。 使用延遲載入就能解決這個問題,讓瀏覽器先載入使用者在當前畫面會看到圖片就好,等到使用者往下捲動時才載入下方的圖片。
延遲載入能帶來什麼好處了?
我認為延遲載入最明顯的好處,有以下三點:
- 節省流量
- 這是一個顯而易見的好處,原本一次要載入全部圖片,現在只需要載入必要圖片,明顯可以節省很多流量的消耗。
- 降低使用者因等待而跳出
- Google研究指出網頁載入在 1~3 秒內,使用者跳出畫面可能性為 32%,超過 5 秒可能性就會大幅增加到 90%,這是一個非常驚人的數據,因此讓使用者越快看到畫面是非常重要的。
- 提升 SEO 成效
- Google 在 2010 年早就公布網站的執行速度將會影響搜尋排名,並且這是屬於中高強度的排名訊號,重要性不言而喻。
延遲載入方法
方法一:使用套件
圖片延遲載入這個議題,從很久以前就已被廣泛討論,因此有很多免費套件都能達成此功能,這邊簡單使用其中一個套件來製作範例程式,以下為範例程式所使用的套件網址。
以下為範例程式碼,沒有太複雜的程式語法,非常簡單易用。
<script src="https://cdn.jsdelivr.net/npm/lazyload@2.0.0-rc.2/lazyload.js"></script>
<img src="loading.svg" data-src="image1.jpg"class="lazyload">
<img src="loading.svg" data-src="image2.jpg"class="lazyload">
<img src="loading.svg" data-src="image3.jpg"class="lazyload">
<img src="loading.svg" data-src="image4.jpg"class="lazyload">
<img src="loading.svg" data-src="image5.jpg"class="lazyload">
<script type="text/javascript">
let images = document.querySelectorAll('img.lazyload');
lazyload(images);
</script>
方法二:使用 Intersection Observer API
如果不喜歡用套件,喜歡自己動手做的話,其實也不會太難,大致上步驟流程如下:
- 先不要讓圖片正常載入畫面。
- 監聽圖片是否進入到可視範圍。
- 圖片進入可視範圍,再載入圖片。
先來看看一個完整的範例
<img src="loading.svg" data-src="image.png" class="lazy">
<script src="https://cdn.jsdelivr.net/npm/intersection-observer@0.12.2/intersection-observer.min.js"></script>
<script type="text/javascript">
const observer = new IntersectionObserver((entries, owner) => {
for (let entry of entries) {
if (entry.isIntersecting) {
// 圖片進入畫面再載入真實照片
const img = entry.target;
img.setAttribute('src', img.dataset.src);
img.removeAttribute('data-src');
owner.unobserve(img);
}
}
});
const images = document.querySelectorAll('img.lazy')
for (let image of images) {
observer.observe(image);
}
</script>
- 行 1:使用 data-src 屬性設定真正要載入的圖片路徑,並用 src 屬性顯示一張載入動畫,讓圖片載入時,不會顯示一片空白,class="lazy" 讓 JavaScript 知道這張圖片要做延遲載入。
- 行 3:目前有支援 Intersection Observer API 的瀏覽器已高達 90% 以上,如果真的擔心有一些老舊瀏覽器不支援的話,可以載入 polyfill 就不用擔心了。
- 行 5、行 16 ~ 19:使用 Intersection Observer API 監聽圖片是否進入到可視範圍,也有人提到可以監聽 scroll、resize 和 orientationchange 事件來達成,但我認為這不是一個好的做法,想想只要稍微滑一下畫面,就會一直重複觸發相同的事件處理,感覺就很吃效能。
- 行 6 ~ 14:當圖片進入可視範圍,就將 src 屬性換成 data-src 屬性的圖片路徑,並且刪除 data-src 屬性及取消監聽。
以上就是完整的範例,有關 Intersection Observer API 在瀏覽器的支援狀況,以及範例中所使用到的 polyfill,可以參考以下網址。
方法三:使用瀏覽器原生支援
使用瀏覽器原生支援大概是最簡單達成延遲載入的方法,您甚至一行 JavaScript 程式碼都無需撰寫就能達成此功能。 只要使用 img 標籤的 loading 屬性,讓瀏覽器自動幫您完成此功能即可,超級簡單。
<img src="image.jpg" loading="lazy">
loading 屬性一共有兩種設定值可供選擇,分別是:
eager:立即載入圖片,無論圖片目前是否在可視範圍,這也是瀏覽器的預設值。
lazy:延遲載入圖片,直到圖片達到與瀏覽器定義的可視範圍距離才載入圖片。
此種方式雖然簡單,但並不是所有的瀏覽器都有原生支援,您可以透過下方網址來了解目前主流瀏覽器的支援狀況。 不過目前語法設計具備向下兼容,就算在瀏覽器不支援的狀況下,只是沒有延遲載入功能而已,並不會影響圖片的呈現。
0 則留言