性能優化Lazy-Load懶加載


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,它們對應到元素上是這樣的:  

![](https://user-gold-cdn.xitu.io/2018/10/5/1664360c6ceda200?w=500&h=500&f=png&s=25422)  

可以看出,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>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM