Lazy loading
Lazy loading(延遲載入)是很實用的開發技巧。在圖片很多的網站使用之後,可以提升頁面載入速度,還能節省網路的流量。
大致上的作法是:
- 一開始圖片不完全載入(src內先不放圖片路徑)
- 觀察圖片是否進入視窗範圍
- 視窗改變後,載入圖片(src內放入圖片路徑)
目前已有幾種方式可以實作。
瀏覽器設定
目前 chrome 瀏覽器已經有加入其功能,但需要自行設定。步驟如下
ps. loading 有三種模式可選
lazy:延遲載入圖片
eager:立即載入圖片
auto:瀏覽器自行決定(Chrome 預設值是 eager)
第三方套件
另外還可以使用其他第三方套件 Lozad.js、lazySize…等等,可上網搜尋 lazyload plugin。
事件監聽
分別要監聽 scroll
(瀏覽器滾動)、resize
(瀏覽器畫面大小調整) 和 orientationchange
(裝置方向改變) 事件,同時透過 Element.getBoundingClientRect()
取得目標元素位置。另外為了避免監聽事件被過度觸發,有時會加上 debounce
(防抖動) 或 throttle
(油門) 兩種方法來處理。最後等圖片完全載入後刪除監聽。使用此種做法似乎會顯得有些麻煩及複雜。
ps.
1.debounce(防抖動) 跟 throttle(油門) 已有 library 可以用:
Lodash
Underscore
2.實作部分於請參考最後的參考資料網站內
Intersection Observer API
這個 API 的功用是當每一個被監控的元素進入(離開)某個元素或 viewport 時,又或者兩者相交達到的一定的次數時觸發執行 callback function。此用法效能比事件監聽好,程式也更加精簡,瀏覽器支援的情況也好。另外也可以應用在 Infinite Scroll、當元素出現在可視範圍內才顯示動畫、計算廣告曝光次數…等需求。
用法範例
1 | const root = document.querySelector('#root'); |
補充:
1.img
標籤設定:
// img 正常載入,callback 後<img class="lazy_img" src="dog.jpg">
// img 無法載入,初始設定<img class="lazy_img" data-src="dog.jpg">
替換圖片路徑用法
// 取 data-src 的值給 srcentry.target.setAttribute('src', img.dataset.src)
entry.target.removeAttribute('data-src')
2.可以先將圖片範圍設定好,用灰底取代。避免跑版。
參考:
https://iandays.com/2019/04/25/reactlazyload/
https://medium.com/@mingjunlu/lazy-loading-images-via-the-intersection-observer-api-72da50a884b7
https://mropengate.blogspot.com/2017/12/dom-debounce-throttle.html
https://blog.camel2243.com/2017/06/05/javascript-throttle-與-debounce,處理頻繁的-callback-執行頻率/
https://mropengate.blogspot.com/2017/12/dom-debounce-throttle.html
https://shubo.io/get-bounding-client-rect/
https://letswrite.tw/intersection-oserver-basic/
https://letswrite.tw/intersection-oserver-demo/
https://pjchender.github.io/2018/06/27/webapis-intersection-observer-api/