1道面試題---懶載入和預載入

洲哥發表於2018-05-30

什麼是懶載入?

懶載入也就是延遲載入。 當訪問一個頁面的時候,先把img元素或是其他元素的背景圖片路徑替換成一張大小為1*1px圖片的路徑(這樣就只需請求一次,俗稱佔點陣圖),只有當圖片出現在瀏覽器的可視區域內時,才設定圖片正真的路徑,讓圖片顯示出來。這就是圖片懶載入。

延遲載入有多種實現,這裡只說其中一種,其實原理都差不多的.

為什麼要使用懶載入?

很多頁面,內容很豐富,頁面很長,圖片較多。比如說各種商城頁面。這些頁面圖片數量多,而且比較大,少說百來K,多則上兆。要是頁面載入就一次性載入完畢。 影響頁面開啟速度,使用者體驗也不好。

懶載入的優點是什麼?

頁面載入速度快、可以減輕伺服器的壓力、節約了流量,使用者體驗好

懶載入的原理是什麼?

頁面中的img元素,如果沒有src屬性,瀏覽器就不會發出請求去下載圖片,只有通過javascript設定了圖片路徑,瀏覽器才會傳送請求。 懶載入的原理就是先在頁面中把所有的圖片統一使用一張佔點陣圖進行佔位,把正真的路徑存在元素的“data-url”(這個名字起個自己認識好記的就行)屬性裡,要用的時候就取出來,再設定為圖片的真實src.

懶載入的實現步驟?

  1. 首先,不要將圖片地址放到src屬性中,而是放到其它屬性(data-original)中。

  2. 頁面載入完成後,根據scrollTop判斷圖片是否在使用者的視野內,如果在,則將data-original屬性中的值取出存放到src屬性中。

  3. 在滾動事件中重複判斷圖片是否進入視野,如果進入,則將data-original屬性中的值取出存放到src屬性中。

實現方式

第一種是純粹的延遲載入,使用setTimeOut或setInterval進行載入延遲.

第二種是條件載入,符合某些條件,或觸發了某些事件才開始非同步下載。

第三種是可視區載入,即僅載入使用者可以看到的區域,這個主要由監控滾動條來實現,一般會在距使用者看到某圖片前一定距離遍開始載入,這樣能保證使用者拉下時正好能看到圖片。

實現程式碼(可視區載入為例)

JS的實現

var imgs = document.getElementsByTagName('img');
// 獲取視口高度與滾動條的偏移量
function lazyload(){
    var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
    var viewportSize = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
    for(var i=0; i<imgs.length; i++) {
	var x =scrollTop+viewportSize-imgs[i].offsetTop;
	if(x>0){
	    imgs[i].src = imgs[i].getAttribute('loadpic');   
	}
    }
}
setInterval(lazyload,1000);
複製程式碼

JQ 的實現:

/**
* 圖片的src實現原理
*/
$(document).ready(function(){
    // 獲取頁面視口高度
    var viewportHeight = $(window).height();
    var lazyload = function() {
       // 獲取視窗滾動條距離
       var scrollTop = $(window).scrollTop();
       $('img').each(function(){
           // 判斷 視口高度+滾動條距離 與 圖片元素距離文件原點的高度		 
           var x = scrollTop + viewportHeight - $(this).position().top;
           // 如果大於0 即該元素能被瀏覽者看到,則將暫存於自定義屬性loadpic的值賦值給真正的src			
           if (x > 0) {
               $(this).attr('src',$(this).attr('loadpic')); 
           }
       })
    }
    // 建立定時器 “實時”計算每個元素的src是否應該被賦值
    setInterval(lazyload,100);
});
複製程式碼

相關文章