[前端]圖片預加載方法 關於圖片的預加載,你所不知道的 關於圖片的預加載,你所不知道的

  目錄javascript

  1. 使用jQuery圖片預加載(延遲加載)插件Lazy Load
  2. 使用JS實現圖片預加載
  3. 使用CSS實現圖片預加載
  4. 使用Ajax實現圖片預加載

1. 使用jQuery圖片預加載(延遲加載)插件Lazy Load

Lazy Load也叫惰性加載,延遲加載,顧名思義,就是在圖片未到達可視區域時,不加載圖片,咱們經常在不少的優秀網站上看到相似的例子,例如迅雷、土豆、優酷等,因爲一個網頁的圖片很是多,一次性加載增長服務器壓力,並且用戶未必會拉到底部,浪費用戶流量,Lazy Load採用按需加載,更快的加載速度從而達到優化網頁的目的。css

使用方法:html

  • 加載jQuery, 並在html代碼的底部包含進來

    <script src="jquery.js" type="text/javascript"></script>
    <script src="jquery.lazyload.js" type="text/javascript"></script>
  • 設置圖片的佔位符爲data-original, 給圖片一個特別的標籤, 像這樣設置圖片

    <img class="lazy" data-original="img/example.jpg" width="640" height="480">
    $(function(){ 
        $("img.lazy").lazyload(); 
    });

    注意:你必須給圖片設置一個height和width,或者在CSS中定義,不然可能會影響到圖片的顯示。前端

  • 插件選項

    圖片預先加載距離:threshold,經過設置這個值,在圖片未出如今可視區域的頂部距離這個值時加載。默認爲0,下面爲設置threshold爲200表示在圖片距離可視區域還有200像素時加載。
    $("img.lazy").lazyload({
        threshold :200
    });

    事件綁定加載的方式:event,你可使用jQuery的事件,例如「click」、「mouseover」,或者你也能夠自定義事件,默認等待用戶滾動,圖片出如今可視區域。下面是使用click:java

    $("img.lazy").lazyload({event:"click"});
    

    顯示效果:effect,默認使用show(),你可使用fadeIn(逐漸出現)方式,代碼以下:jquery

    $("img.lazy").lazyload({
        effect :"fadeIn"
    });
    

    對於禁用javascript的瀏覽器則要加上noscript內容:css3

    <img class="lazy" data-original="img/example.jpg" width="640" heigh="480">
    <noscript><img src="img/example.jpg" alt="jQuery圖片預加載(延遲加載)插件Lazy Load" width="640" heigh="480"></noscript>

    圖片限定在某個容器內:container,你能夠經過限定某個容器內容的圖片纔會生效,代碼以下:web

    #container {
        height:600px;
        overflow: scroll;
    }
    $("img.lazy").lazyload({
         container: $("#container")
    });  

  原文連接: jQuery圖片預加載(延遲加載)插件Lazy Loadajax

2. JS實現圖片預加載

  在瀏覽器渲染圖片的時候, 它得到圖片的一片區域的時候, 就已經爲這張圖片預留了一片空白的區域來填充圖片, 這就是預加載得到圖片尺寸最原始的使用方法.數組

  有時候會加載一些在當前頁面沒有用到的圖片,是爲了提早加載到緩存裏,這樣後面的頁面就能夠直接從緩存讀取了。

  加載大圖的時候,咱們能夠先顯示模糊的縮略圖,等到大圖加載完了,再把縮略圖替換掉,這樣填補了圖片加載期間的空白時間。

  image也有onload和onerror事件,分別是加載完後和加載失敗時執行。

  Image對象是專門用於處理圖片加載的,就至關於內存中的img標籤。

  圖片預加載案例:鼠標移入一張圖片時,換成另外一張圖片,移出時換回原來的圖片。正常作法是,鼠標移入的時候,改變圖片的src,但這時就要去加載圖片了,會等待一段時間,這樣體驗很差。預加載的作法是,在頁面加載完,鼠標移入以前就經過Image對象把圖片加載進緩存了,這樣鼠標移入的時候直接從緩存裏讀取了,速度很快。

  • 圖片預加載:

        if(document.images){
            var img = new Image();
            img.src = "img/example.jpg";
        }

 

  • 封裝成一個預加載圖片的函數

        //實現圖片的預加載
        function preloadImg(srcArr){
            if(srcArr instanceof Array){
                for(var i=0; i<srcArr.length; i++){
                    var oImg = new Image();
                    oImg.src = srcArr[i];
                }
            }
        }
    
        //預加載圖片
        preloadImg(['image/example.jpg']);  //參數是一個url數組  
  • 使用一個回調函數來得到圖片的屬性

        function getPreloadImgAttr(url,callback){
            var oImg = new Image(); //建立一個Image對象,實現圖片的預加載
            oImg.src = url;      // 看下一節,其實應當先進行onload的綁定,再賦值給src
            if(oImg.complete){
                //若是圖片已經存在於瀏覽器緩存,直接調用回調函數
                callback.call(oImg);
                return; //直接返回,再也不處理onload事件
            }
            oImg.onload = function(){
                //圖片下載完畢時異步調用callback函數
                callback.call(oImg);    
            };
        }
        getPreloadImgAttr('image/example.jpg',function(){
            console.log(this.width, this.height);
        });  
  • 關於預加載圖片的改進

    網上看到一篇博客關於圖片的預加載,你所不知道的, 其中指出以上通用的方法存在一些問題:
    • 建立了一個臨時匿名函數來做爲圖片的onload事件處理函數,造成了閉包。

      相信你們都看到過ie下的內存泄漏模式的文章,其中有一個模式就是循環引用,而閉包就有保存外部運行環境的能力(依賴於做用域鏈的實現),因此img.onload這個函數內部又保存了對img的引用,這樣就造成了循環引用,致使內存泄漏。(這種模式的內存泄漏只存在低版本的ie6中,打過補丁的ie6以及高版本的ie都解決了循環引用致使的內存泄漏問題)。

    • 只考慮了靜態圖片的加載,忽略了gif等動態圖片,這些動態圖片可能會屢次觸發onload。
    •   改進方法:
      function loadImage(url, callback) {     
          var img = new Image(); //建立一個Image對象,實現圖片的預下載     
          img.onload = function(){
              img.onload = null;
              callback(img);
          }
          img.src = url; 
      }
      

        這樣內存泄漏,動態圖片的加載問題都獲得瞭解決,並且也以統一的方式,實現了callback的調用。
      關於這個方法, 有個疑問是緩存的問題, 在原文裏也給出了一些解釋

      通過對多個瀏覽器版本的測試,發現ie、opera下,當圖片加載過一次之後,若是再有對該圖片的請求時,因爲瀏覽器已經緩存住這張圖
      片了,不會再發起一次新的請求,而是直接從緩存中加載過來。對於 firefox和safari,它們試圖使這兩種加載方式對用戶透明,一樣
      會引發圖片的onload事件,而ie和opera則忽略了這種同一性,不會引發圖片的onload事件,所以上邊的代碼在它們裏邊不能得以實
      現效果。

      但總體來說,仍然應該先進行onload事件的綁定, 再賦值src

  參考:[前端] 圖片預加載及獲取屬性  關於圖片的預加載,你所不知道的

3. 用CSS實現圖片的預加載

  這個概念就是寫一個CSS樣式設置一批背景圖片,而後將其隱藏,這樣你就看不到那些圖片了。那些背景圖片就是你想預載的圖片。

#preload-01 { background: url(http://domain.tld/image-01.png) no-repeat -9999px -9999px; }  
#preload-02 { background: url(http://domain.tld/image-02.png) no-repeat -9999px -9999px; }  
#preload-03 { background: url(http://domain.tld/image-03.png) no-repeat -9999px -9999px; }

  這裏爲了隱藏這些圖片, 使用了位置設置爲極大的負值的方法. 還能夠直接設置 { width: 0; height: 0; display: none};

  該方法雖然高效,但仍有改進餘地。使用該法加載的圖片會同頁面的其餘內容一塊兒加載,增長了頁面的總體加載時間。爲了解決這個問題,咱們增長了一些JavaScript代碼,來推遲預加載的時間,直到頁面加載完畢。代碼以下:

// better image preloading @ <a href="http://perishablepress.com/press/2009/12/28/3-ways-preload-images-css-javascript-ajax/">http://perishablepress.com/press/2009/12/28/3-ways-preload-images-css-javascript-ajax/</a>  
function preloader() {  
    if (document.getElementById) {  
        document.getElementById("preload-01").style.background = "url(http://domain.tld/image-01.png) no-repeat -9999px -9999px";  
        document.getElementById("preload-02").style.background = "url(http://domain.tld/image-02.png) no-repeat -9999px -9999px";  
        document.getElementById("preload-03").style.background = "url(http://domain.tld/image-03.png) no-repeat -9999px -9999px";  
    }  
}  
function addLoadEvent(func) {  
    var oldonload = window.onload;  
    if (typeof window.onload != 'function') {  
        window.onload = func;  
    } else {  
        window.onload = function() {  
            if (oldonload) {  
                oldonload();  
            }  
            func();  
        }  
    }  
}  
addLoadEvent(preloader);

  在該腳本的第一部分,咱們獲取使用類選擇器的元素,併爲其設置了background屬性,以預加載不一樣的圖片。

  該腳本的第二部分,咱們使用addLoadEvent()函數來延遲preloader()函數的加載時間,直到頁面加載完畢。

  若是JavaScript沒法在用戶的瀏覽器中正常運行,會發生什麼?很簡單,圖片不會被預加載,當頁面調用圖片時,正常顯示便可。

  參考: 純CSS圖片預加載  Javascript圖片預加載詳解

4. 使用Ajax實現預加載

  該方法利用DOM,不只僅預加載圖片,還會預加載CSS、JavaScript等相關的東西。使用Ajax,比直接使用JavaScript,優越之處在於JavaScript和CSS的加載不會影響到當前頁面。該方法簡潔、高效。

window.onload = function() {  
    setTimeout(function() {  
        // XHR to request a JS and a CSS  
        var xhr = new XMLHttpRequest();  
        xhr.open('GET', 'http://domain.tld/preload.js');  
        xhr.send('');  
        xhr = new XMLHttpRequest();  
        xhr.open('GET', 'http://domain.tld/preload.css');  
        xhr.send('');  
        // preload image  
        new Image().src = "http://domain.tld/preload.png";  
    }, 1000);  
};  

  上面代碼預加載了「preload.js」、「preload.css」和「preload.png」。1000毫秒的超時是爲了防止腳本掛起,而致使正常頁面出現功能問題。

  與之相比, 若是用js的話, 要實現以上加載過程則會應用到頁面上. 實現以下

window.onload = function() {  
  
    setTimeout(function() {  
  
        // reference to <head>  
        var head = document.getElementsByTagName('head')[0];  
  
        // a new CSS  
        var css = document.createElement('link');  
        css.type = "text/css";  
        css.rel  = "stylesheet";  
        css.href = "http://domain.tld/preload.css";  
  
        // a new JS  
        var js  = document.createElement("script");  
        js.type = "text/javascript";  
        js.src  = "http://domain.tld/preload.js";  
  
        // preload JS and CSS  
        head.appendChild(css);  
        head.appendChild(js);  
  
        // preload image  
        new Image().src = "http://domain.tld/preload.png";  
  
    }, 1000);  
  
};

 

  這裏,咱們經過DOM建立三個元素來實現三個文件的預加載。正如上面提到的那樣,使用Ajax,加載文件不會應用到加載頁面上。從這點上看,Ajax方法優越於JavaScript。

  參考: Javascript圖片預加載詳解

相關文章
相關標籤/搜索