1. 程式人生 > >佔位圖和圖片懶載入專案實戰詳解

佔位圖和圖片懶載入專案實戰詳解

佔位圖(兜底圖):

真實圖片太大還沒有載入完之前先用一張佔位圖表示這個位置將來會有圖片或者說明這個位置是有圖片的但是不知道什麼原因真正的圖片沒有加載出來使用者只能看到這張佔位圖;

什麼是圖片懶載入:

懶載入也就是延遲載入,當訪問一個頁面的時候,先把img元素渲染出來,但是不給它真正的src地址,只有當用戶需要看到真正圖片的時候,才設定圖片正真的路徑,讓圖片顯示出來。

為什麼要使用懶載入:

在一個頁面中,假設有20張圖片,每張為100kb,使用者在不點滾動條的時候看到的只有4張,如果這20張圖片都設定了真正的src,那麼當頁面首次載入的時候瀏覽器會立即請求這20張圖片資源,需要2000kb的流量;
但是我們做懶載入只請求使用者看到的4張圖片的話,瀏覽器只請求這4張圖片資源,需要的流量只有400kb。這種手段可以大大減少首屏時間。

懶載入的實現步驟:

1)首先,不要將真正的圖片地址放到src屬性中,此時放到src中的是一張兜底圖,而是放到其它屬性(picAddress)中。
2)頁面載入完成後,根據scrollTop判斷圖片是否在使用者的視野內,如果在,則將picAddress屬性中的值取出存放到src屬性中。
3)在滾動事件中重複判斷圖片是否進入視野,如果進入,則將picAddress屬性中的值取出存放到src屬性中。

案例:

這裡寫圖片描述

index.html

<html>
    <head>
        <meta charset="utf-8">
    </head
>
<body> <style> body{ text-align: center; } .game-detail-logo{ width: 750px; height: 430px; text-align: center; margin-top:30px; } </style
>
<img src="https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=4259389730,3152819071&fm=26&gp=0.jpg" class="game-detail-logo lazyLoadImg" picAddress="https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=4003935283,4035293154&fm=27&gp=0.jpg"> <img src="https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=4259389730,3152819071&fm=26&gp=0.jpg" class="game-detail-logo lazyLoadImg" picAddress="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1535003204948&di=7f297fc3bd01dcbca58f47c470ae9b9e&imgtype=0&src=http%3A%2F%2Fpic50.nipic.com%2Ffile%2F20141019%2F19104397_104929568000_2.jpg"> <img src="https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=4259389730,3152819071&fm=26&gp=0.jpg" class="game-detail-logo lazyLoadImg" picAddress="http://i1.hdslb.com/bfs/archive/062705867631af9f8e83aadf6d8a1f935b25cbc2.jpg"> <img src="https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=4259389730,3152819071&fm=26&gp=0.jpg" class="game-detail-logo lazyLoadImg" picAddress="https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2390937513,1169699994&fm=27&gp=0.jpg"> <img src="https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=4259389730,3152819071&fm=26&gp=0.jpg" class="game-detail-logo lazyLoadImg" picAddress="https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6169699994&fm=27&gp=0.jpg"> <img src="https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=4259389730,3152819071&fm=26&gp=0.jpg" class="game-detail-logo lazyLoadImg" picAddress="https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=3947968217,2342505746&fm=27&gp=0.jpg"> </body> <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script> <script type="text/javascript" src="lazyLoadImg.js"></script> </html>

lazyLoadImg.js


/* 
* @example
* <img src="" class="lazyLoadImg" picAddress="">
* @param src裡面寫的是佔位圖或者說兜底圖地址(一張預設填充圖)
* @param class="lazyLoadImg" 是必須的標識
* @param picAddress裡面寫的是真正需要懶載入的圖片地址
*/
const lazyLoadImg = {
  initConfig() {
    const self = this;
    self.imgObject.srcFlag = 'picAddress'; // 圖片地址
    self.imgObject.class = 'lazyLoadImg'; // 惰性載入的圖片需要新增的class
    self.imgObject.sensitivity = 40; // 滑鼠滾動敏感度,該值越小,惰性越強(載入越少)
    self.imgObject.init();
  },
  imgObject: {
    trigger() {
      const self = this;
      const eventType = (self.isPhone && 'touchend') || 'scroll';
      self.imgListData = $('img.' + self.class + '');
      $(window).trigger(eventType);
    },
    init() {
      var self = this;
      $(window).on('scroll', function() {
        self.isLoadImg();
      });
      self.trigger();
    },
    isLoadImg() {
      const self = this;
      function loadNeedImg(img) { // 判斷哪些img元素需要載入
        const windowPageYOffset = window.pageYOffset; // 滾動條距離視窗頂部的偏移量
        const offsetAddInner = window.pageYOffset + window.innerHeight; // window.innerHeight返回視窗的文件顯示區的高度
        const imgOffsetTop = img.offset().top; // 當前img元素距離視窗頂部的偏移量
        return (
          imgOffsetTop >= windowPageYOffset && // 確保img元素在視窗內
          imgOffsetTop - self.sensitivity <= offsetAddInner //當前img元素是不是在視窗可見範圍內,不可見返回:false
        );
      }
      function loadImg(img, index) {
        const imgUrl = img.attr(self.srcFlag);
        const imgLazy = img.attr('src');
        img.attr('src', imgUrl);
        img[0].onload ||  // 開始向伺服器請求載入圖片
          ((img[0].onload = function() {
            $(this)
              .removeClass(self.class)
              .removeAttr(self.srcFlag),
            (self.imgListData[index] = null),
            (this.onerror = this.onload = null);
          }),
            (img[0].onerror = function() {
              (this.src = imgLazy),
              $(this)
                .removeClass(self.class)
                .removeAttr(self.srcFlag),
              (self.imgListData[index] = null),
              (this.onerror = this.onload = null);
            }));
      }
      self.imgListData.each(function(index, val) {
        if (!val) return;
        const img = $(val);
        if (!loadNeedImg(img)) return;
        const aa = img.attr(self.srcFlag);
        if (!img.attr(self.srcFlag)) return;// 判斷是否有規定的picAddress屬性,沒有則退出當次迴圈
        loadImg(img, index);
      });
    },
  },
};
lazyLoadImg.initConfig();

案例執行注意點:

1)將瀏覽器變成手機除錯模式,Chrome最佳
2)手機模式後高度不能太高(越矮越好),需要出現滾動條,以便滾動下去測試後面的圖片
3)網路限速將online設成mid-tier mobile或者low-end mobile更容易看到效果

案例效果:

首次執行時,會先出現佔位圖(兜底圖),然後載入其他圖片;當滾動到後面的圖片時再按需請求對應的圖片資源