頁面性能優化-原生JS實現圖片懶加載


 

   在項目開發中,我們往往會遇到一個頁面需要加載很多圖片的情況。我們可以一次性加載全部的圖片,但是考慮到用戶有可能只瀏覽部分圖片。所以我們需要對圖片加載進行優化,只加載瀏覽器窗口內的圖片,當用戶滾動時,再加載更多的圖片。這種加載圖片的方式叫做圖片懶加載,又叫做按需加載或圖片的延時加載。這樣做的好處是:1.可以加快頁面首屏渲染的速度;2.節約用戶的流量。

一.實現思路

1.圖片img標簽自定義一個屬性data-src來存放真實的地址。

2.當滾動頁面時,檢查所有的img標簽,判斷是否出現在事業中,如果出現在視野中,繼續進行判斷,看齊是否被加載過了,如果沒有加載,那就進行加載。

判斷圖片元素是否處於瀏覽器視野中的示意圖(手繪):

二.根據思路完成代碼如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>原生js實現圖片懶加載</title>
  <style>
    *{
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    ul{
      overflow: hidden;
      list-style: none;
    }
    li{
      float: left;
      width: 50%;
      height: 200px;
      padding: 10px;
    }
    li img{
      display: inline-block;
      width: 100%;
      height: 100%;
    }
  </style>
</head>
<body>
<div class="container">
  <ul>
    <li><img src="http://cdn.jirengu.com/book.jirengu.com/img/1.jpg" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/1.jpg"></li>
    <li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/2.jpg"></li>
    <li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/3.jpg"></li>
    <li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/4.jpg"></li>
    <li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/5.jpg"></li>
    <li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/6.jpg"></li>
    <li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/7.jpg"></li>
    <li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/8.jpg"></li>
    <li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/9.jpg"></li>
    <li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/10.jpg"></li>
    <li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/11.jpg"></li>
    <li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/12.jpg"></li>
    <li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/13.jpg"></li>
    <li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/14.jpg"></li>
    <li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/15.jpg"></li>
    <li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/16.jpg"></li>
  </ul>
</div>
<script>
  // window綁定滾動事件
  window.addEventListener('scroll',function(){
    // 遍歷所有的img標簽
    Array.prototype.slice.apply(document.getElementsByTagName('li')).forEach((li)=>{
      let img=li.getElementsByTagName('img')[0];
      // 判斷當前img是否出現在了視野中
      // 判斷當前img是否被加載過了
      if(checkShow(img) && !isLoaded(img)){
        loadImg(img);
      }
    })
  });

  // 判斷img是否出現瀏覽器視野中
  function checkShow(img) {
    let scrollTop=document.documentElement.scrollTop; // 頁面向上滾動的高度
    let windowHeight=window.innerHeight; //瀏覽器自身高度
    let offsetTop=img.offsetTop; //目標標簽相對於document的高度
    return (offsetTop > scrollTop && offsetTop <(windowHeight + scrollTop));
  }

  // 判斷是否已經加載過
  function isLoaded(img) {
    return img.getAttribute('src')===img.getAttribute('data-src');
  }

  // 加載圖片
  function loadImg(img) {
   img.setAttribute('src',img.getAttribute('data-src'));
  }
</script>
</body>
</html>

好了,在瀏覽器中運行一下,第一次進頁面如果不滾動滾輪的話什么也看不到,所以第一次進頁面需要調用checkShow(),處於視野中的圖片也加載出來。

在代碼最后加上:

// 第一次進頁面加載處於視野中的圖片
 Array.prototype.slice.apply(document.getElementsByTagName('li')).forEach((li)=>{
    let img=li.getElementsByTagName('img')[0];
    // 判斷當前img是否出現在了視野中
    // 判斷當前img是否被加載過了
    if(checkShow(img) && !isLoaded(img)){
      loadImg(img);
    }
  })

此時我們發現判斷加載視野中的圖片代碼存在重復,直接封裝成一個新的方法lazyRenderImg();

// window綁定滾動事件
  window.addEventListener('scroll',function(){
    // 遍歷所有的img標簽
    lazyRenderImg();
  });

function lazyRenderImg(){
 Array.prototype.slice.apply(document.getElementsByTagName('li')).forEach((li)=>{
      let img=li.getElementsByTagName('img')[0];
      // 判斷當前img是否出現在了視野中
      // 判斷當前img是否被加載過了
      if(checkShow(img) && !isLoaded(img)){
        loadImg(img);
      }
    })
  }

  // 第一次進頁面加載處於視野中的圖片
  lazyRenderImg();

 三.性能優化

問題:window.scroll 方法頁面只要一滾動就會觸發里面的方法,對性能影響很大

解決方法:當頁面停止滾動的時候,再去執行頁面中的方法,類似與函數節流(throttle)

Tips:函數節流:等時間間隔執行函數, 讓一個函數不要執行得太頻繁,減少一些過快的調用來節流。

// window綁定滾動事件
  let timer;
  window.addEventListener('scroll',function(){
console.log('scroll')
// 遍歷所有的img標簽 if(timer){ clearTimeout(timer) } timer=setTimeout(()=>{
console.log('lazyRenderImg...'); lazyRenderImg(); },
300);

通過打印的日志發現當滾動停止后才執行lazyRenderImg方法的,確實減少了不必要調用lazyRenderImg的次數。

    頁面性能優化之圖片懶加載就寫這么多了,網頁優化還有很多方法與技巧,前端路漫漫其修遠兮,吾將上下而求索。本文不足之處,請多指正。

 


 

參考資料:

https://www.jianshu.com/p/1b32e16ed0e5

 

 

 


免責聲明!

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



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