Lazy-Load,翻譯過來是“
懶加載”。它是針對圖片加載時機的優化:在一些圖片量比較大的網站(比如電商網站首頁,或者團購網站、小游戲首頁等),如果我們嘗試在用戶打開頁面的時候,就把所有的圖片資源加載完畢,那么很可能會造成白屏、卡頓等現象,因為圖片真的太多了,一口氣處理這么多任務,瀏覽器做不到啊!
但我們再想,用戶真的需要這么多圖片嗎?不對,用戶點開頁面的瞬間,呈現給他的只有屏幕的一部分(我們稱之為首屏)。只要我們可以在頁面打開的時候把首屏的圖片資源加載出來,用戶就會認為頁面是沒問題的。至於下面的圖片,我們完全可以等用戶下拉的瞬間再即時去請求、即時呈現給他。這樣一來,性能的壓力小了,用戶的體驗卻沒有變差——這個延遲加載的過程,就是 Lazy-Load。
什么是圖片懶加載?
當訪問一個頁面的時候,先把img元素或是其他元素的背景圖片路徑替換成一張大小為1*1px圖片的路徑(這樣就只需請求一次),當圖片出現在瀏覽器的可視區域內時,才設置圖片真正的路徑,讓圖片顯示出來。這就是圖片懶加載。
通俗一點:
1、就是創建一個自定義屬性data-src存放真正需要顯示的圖片路徑,而img自帶的src放一張大小為1 * 1px的圖片路徑。
2、當頁面滾動直至此圖片出現在可視區域時,用js取到該圖片的data-src的值賦給src。
ps:自定義屬性可以取任何名字
<body>
<div class="container">
<div class="img">
// 注意我們並沒有為它引入真實的src
<img class="pic" alt="加載中" data-src="./images/1.png">
</div>
<div class="img">
<img class="pic" alt="加載中" data-src="./images/2.png">
</div>
<div class="img">
<img class="pic" alt="加載中" data-src="./images/3.png">
</div>
<div class="img">
<img class="pic" alt="加載中" data-src="./images/4.png">
</div>
<div class="img">
<img class="pic" alt="加載中" data-src="./images/5.png">
</div>
<div class="img">
<img class="pic" alt="加載中" data-src="./images/6.png">
</div>
<div class="img">
<img class="pic" alt="加載中" data-src="./images/7.png">
</div>
<div class="img">
<img class="pic" alt="加載中" data-src="./images/8.png">
</div>
<div class="img">
<img class="pic" alt="加載中" data-src="./images/9.png">
</div>
<div class="img">
<img class="pic" alt="加載中" data-src="./images/10.png">
</div>
</div>
</body>
在懶加載的實現中,有兩個關鍵的數值:一個是**
當前可視區域的高度**,另一個是**
元素距離可視區域頂部的高度**。
**當前可視區域的高度**, 在和現代瀏覽器及 IE9 以上的瀏覽器中,可以用 window.innerHeight 屬性獲取。在低版本 IE 的標准模式中,可以用 document.documentElement.clientHeight 獲取,這里我們兼容兩種情況:
const viewHeight = window.innerHeight || document.documentElement.clientHeight
而**元素距離可視區域頂部的高度**,我們這里選用 getBoundingClientRect() 方法來獲取返回元素的大小及其相對於視口的位置。對此 MDN 給出了非常清晰的解釋:
> 該方法的返回值是一個 DOMRect 對象,這個對象是由該元素的 getClientRects() 方法返回的一組矩形的集合, 即:是與該元素相關的 CSS 邊框集合 。
> DOMRect 對象包含了一組用於描述邊框的只讀屬性——left、top、right 和 bottom,單位為像素。除了 width 和 height 外的屬性都是相對於視口的左上角位置而言的。
其中需要引起我們注意的就是 left、top、right 和 bottom,它們對應到元素上是這樣的:

可以看出,top 屬性代表了元素距離可視區域頂部的高度,正好可以為我們所用!
Lazy-Load 方法開工啦!
<script>
// 獲取所有的圖片標簽
const imgs = document.getElementsByTagName('img')
// 獲取可視區域的高度
const viewHeight = window.innerHeight || document.documentElement.clientHeight
// num用於統計當前顯示到了哪一張圖片,避免每次都從第一張圖片開始檢查是否露出
let num = 0
function lazyload(){
for(let i=num; i<imgs.length; i++) {
// 用可視區域高度減去元素頂部距離可視區域頂部的高度
let distance = viewHeight - imgs[i].getBoundingClientRect().top
// 如果可視區域高度大於等於元素頂部距離可視區域頂部的高度,說明元素露出
if(distance >= 0 ){
// 給元素寫入真實的src,展示圖片
imgs[i].src = imgs[i].getAttribute('data-src')
// 前i張圖片已經加載完畢,下次從第i+1張開始檢查是否露出
num = i + 1
}
}
}
// 監聽Scroll事件
window.addEventListener('scroll', lazyload, false);
</script>