懶加載和預加載

參考連接:javascript

懶加載和預加載html

懶加載的原理及實現java

處理圖片預加載時設置img的src屬性和img的onload事件的位置先後順序關係node

關於圖片的預加載,你所不知道的瀏覽器

 

  • 頁面中的img元素,若是沒有src屬性,瀏覽器就不會發出請求去下載圖片,只有經過javascript設置了圖片路徑,瀏覽器纔會發送請求。
  • 加載圖片的過程是異步的

   

1、懶加載 緩存

  1. 介紹
    • 懶加載也就是延遲加載。
    • 當訪問一個頁面的時候,先把全部img標籤的src設爲同一張空白圖片的路徑(佔位圖,只需請求一次),將其真正的圖片地址存儲在img標籤的自定義屬性中(好比data-src)
    • 兩種加載狀況:
      • 條件加載:符合某些條件,或觸發了某些事件,纔將自定義屬性中的地址存儲到src屬性中,開始異步加載
      • 可視區加載:僅加載用戶能夠看到的區域。當js監聽到該圖片元素進入可視窗口時,將自定義屬性中的地址存儲到src屬性中,開始異步加載。

         

                        var lazyLoad = (function(){
                            var clock;
                            
                            function init(){
                                //監聽瀏覽器滾動事件,持續滾動後停留200ms纔會觸發checkShow()
                                $(window).on("scroll", function(){
                                    if (clock) {
                                        clearTimeout(clock);
                                    }
                                    clock = setTimeout(function(){
                                        checkShow();
                                    }, 200);
                                })
                                checkShow();
                            }
                            
                            function checkShow(){
                                $(".lazyload img").each(function(){
                                    var $cur =$(this);
                                    //若某圖片已經顯示,則return
                                    if($cur.attr('isLoaded')){
                                        return;
                                    }
                                    //若某圖片應該顯示卻還未顯示,則將其顯示出來
                                    if(shouldShow($cur)){
                                        showImg($cur);
                                    }
                                })
                            }
                            //判斷圖片是否應該顯示
                            function shouldShow($node){
                                var scrollH = $(window).scrollTop(), //窗口的垂直滾動條位置
                                    winH = $(window).height(), //窗口高度
                                    top = $node.offset().top;  //圖片相對於整個文檔的偏移top座標
                                if(top < winH + scrollH){
                                    return true;
                                }else{
                                    return false;
                                }
                            }
                            //將圖片顯示出來
                            function showImg($node){
                                $node.attr('src', $node.attr('data-src'));
                                $node.attr('isLoaded', true);
                            }
                            return {
                                init: init
                            }
                        })()
                        lazyLoad.init();

         

         

         

  2. 目的
    • 不少頁面,內容很豐富,頁面很長,圖片較多,並且比較大。
    • 懶加載能防止頁面一次性向服務器響應大量請求致使服務器響應慢,頁面卡頓或崩潰等問題。
    • 減小請求數或延遲請求數,使頁面加載速度快,用戶體驗好

   

2、預加載 服務器

  1. 介紹
    • 提早加載圖片,當用戶須要查看時可直接從本地緩存中渲染
  2. 目的
    • 圖片預先加載到瀏覽器中,訪問者即可順利地在你的網站上衝浪,並享受到極快的加載速度。
    • 這對圖片畫廊及圖片佔據很大比例的網站來講十分有利,它保證了圖片快速、無縫地發佈,也可幫助用戶在瀏覽你網站內容時得到更好的用戶體驗。
  3. 實現
    • 方法一 ×

       

                  function loadImage(url, callback) {     
                      var img = new Image(); //建立一個Image對象,實現圖片的預下載     
                      img.onload = function () { //圖片下載完畢時調用callback函數。         
                         callback(img);     
                       };  
                      img.src = url;     
      };

       

      • 注意:要將 img.src放在img.onload後面
        • 不然,若將img .src放在img.onload前面
          • 若沒有緩存:沒問題
            • img.src賦值後開始異步加載圖片,加載過程的時間很長,當加載完圖片時,onload的賦值語句已經執行,因此加載完圖片發生onload事件時就會調用callback函數。
          • 如有緩存,有問題
            • img.src賦值後開始異步加載圖片,加載過程的時間很短,當加載完圖片時,尚未執行到onload的賦值語句,因此加載完圖片發生onload事件時不會調用callback函數。
      • 問題:
        • 內存泄漏:img.onload引用的匿名函數造成了閉包,閉包的做用域鏈中保存着img,建立了循環引用
        • 只考慮了靜態圖片的加載,忽略了gif等動態圖片,可能會屢次觸發onload
    • 方法二 √:解決方法一的問題

       

                  function loadImage(url, callback) {     
                      var img = new Image(); //建立一個Image對象,實現圖片的預下載         
                      img.onload = function () { //圖片下載完畢時將img.onload設爲null,並異步調用callback函數。         
                          img.onload = null;    
                          callback(img);     
                      };  
                      img.src = url;     
      };
相關文章
相關標籤/搜索