延遲加載(Lazyload)三種實現方式

定義:延遲加載也稱為惰性加載,即在長網頁中延遲加載圖像。用戶滾動到它們之前,視口外的圖像不會加載。這與圖像預加載相反,在長網頁上使用延遲加載將使網頁加載更快。在某些情況下,它還可以幫助減少服務器負載。

舉個例子來說明,當打開淘寶首頁的時候,只有在瀏覽器窗口裡的圖片才會被加載,當你滾動首頁向下滑的時候,進入視口內的圖片才會被加載,而其它從未進入視口的圖像不會也不會加載。

那麼延遲加載有什麼好處:

【1】首先它能提升用戶的體驗,試想一下,如果打開頁面的時候就將頁面上所有的圖片全部獲取加載,如果圖片數量較大,對於用戶來說簡直就是災難,會出現卡頓現象,影響用戶體驗。

【2】有選擇性地請求圖片,這樣能明顯減少了服務器的壓力和流量,也能夠減小瀏覽器的負擔。

那麼下面就介紹延遲加載的三種實現方式:


第一種

首先將頁面上的圖片的 src 屬性設為 loading.gif,而圖片的真實路徑則設置在 data-src 屬性中,頁面滾動的時候計算圖片的位置與滾動的位置,當圖片出現在瀏覽器視口內時,將圖片的 src 屬性設置為 data-src 的值,這樣,就可以實現延遲加載。

下面是具體的實現代碼:

延遲加載(Lazyload)三種實現方式

比較 image 的 offsetTop 與 seeHeight + scrollTop 的大小,當小於時則說明圖片已經出現過在視口中,這時候繼續判斷圖片是否已經替換過,如果沒有替換過,則進行替換。

實現的效果:不斷滑動頁面時,圖片延遲加載

延遲加載(Lazyload)三種實現方式

需要提及的是變量 n 是用來保存已經加載的圖片數量,避免每次都從第一張圖片開始遍歷,提升性能。


第二種

上面的代碼是沒什麼問題,但是性能偏差。如果直接將函數綁定在 scroll 事件上,當頁面滾動時,函數會被高頻觸發,這非常影響瀏覽器的性能。我粗略地估計一下,當簡單地滾動一下頁面,函數至少觸發了十來次,這顯然是十分沒必要的。

所以在做事件綁定的時候,可以對 lazyload 函數進行函數節流(throttle)與函數去抖(debounce)處理。

簡單說來:

【1】Debounce:一部電梯停在某一個樓層,當有一個人進來後,20秒後自動關門,這20秒的等待期間,又一個人按了電梯進來,這20秒又重新計算,直到電梯關門那一刻才算是響應了事件。

【2】Throttle:好比一臺自動的飲料機,按拿鐵按鈕,在出飲料的過程中,不管按多少這個按鈕,都不會連續出飲料,中間按鈕的響應會被忽略,必須要等這一杯的容量全部出完之後,再按拿鐵按鈕才會出下一杯。

下面就是經過 throttle 處理後的代碼:

延遲加載(Lazyload)三種實現方式

設置了 500ms 的延遲,和 1000ms 的間隔,當超過 1000ms 未觸發該函數,則立即執行該函數,不然則延遲 500ms 執行該函數。

實現效果:可以看出有一定的延遲。

延遲加載(Lazyload)三種實現方式


第三種: 使用 IntersectionObserver API

實現代碼:簡潔,但是瀏覽器尚未全部實現。

延遲加載(Lazyload)三種實現方式

IntersectionObserver 傳入一個回調函數,當其觀察到元素集合出現時候,則會執行該函數。

io.observe 即要觀察的元素,要一個個添加才可以。

io 管理的是一個數組,當元素出現或消失的時候,數組添加或刪除該元素,並且執行該回調函數。

實現效果:

延遲加載(Lazyload)三種實現方式


分享到:


相關文章: