1. 使用jQuery圖片預加載(延遲加載)插件Lazy Load
Lazy Load也叫惰性加載,延遲加載,顧名思義,就是在圖片未到達可視區域時,不加載圖片,咱們經常在不少的優秀網站上看到相似的例子,例如迅雷、土豆、優酷等,因爲一個網頁的圖片很是多,一次性加載增長服務器壓力,並且用戶未必會拉到底部,浪費用戶流量,Lazy Load採用按需加載,更快的加載速度從而達到優化網頁的目的。javascript
使用方法:css
-
加載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">
123$(
function
(){
$(
"img.lazy"
).lazyload();
});
注意:你必須給圖片設置一個height和width,或者在CSS中定義,不然可能會影響到圖片的顯示。html
-
插件選項
圖片預先加載距離:threshold,經過設置這個值,在圖片未出如今可視區域的頂部距離這個值時加載。默認爲0,下面爲設置threshold爲200表示在圖片距離可視區域還有200像素時加載。$("img.lazy").lazyload({ threshold :200 });
事件綁定加載的方式:event,你可使用jQuery的事件,例如「click」、「mouseover」,或者你也能夠自定義事件,默認等待用戶滾動,圖片出如今可視區域。下面是使用click:前端
1$(
"img.lazy"
).lazyload({event:
"click"
});
顯示效果:effect,默認使用show(),你可使用fadeIn(逐漸出現)方式,代碼以下:java
123$(
"img.lazy"
).lazyload({
effect :
"fadeIn"
});
對於禁用javascript的瀏覽器則要加上noscript內容:jquery
<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,你能夠經過限定某個容器內容的圖片纔會生效,代碼以下:css3
#container { height:600px; overflow: scroll; }
$("img.lazy").lazyload({ container: $("#container") });
原文連接: jQuery圖片預加載(延遲加載)插件Lazy Loadweb
2. JS實現圖片預加載
在瀏覽器渲染圖片的時候, 它得到圖片的一片區域的時候, 就已經爲這張圖片預留了一片空白的區域來填充圖片, 這就是預加載得到圖片尺寸最原始的使用方法.ajax
有時候會加載一些在當前頁面沒有用到的圖片,是爲了提早加載到緩存裏,這樣後面的頁面就能夠直接從緩存讀取了。數組
加載大圖的時候,咱們能夠先顯示模糊的縮略圖,等到大圖加載完了,再把縮略圖替換掉,這樣填補了圖片加載期間的空白時間。
image也有onload和onerror事件,分別是加載完後和加載失敗時執行。
Image對象是專門用於處理圖片加載的,就至關於內存中的img標籤。
圖片預加載案例:鼠標移入一張圖片時,換成另外一張圖片,移出時換回原來的圖片。正常作法是,鼠標移入的時候,改變圖片的src,但這時就要去加載圖片了,會等待一段時間,這樣體驗很差。預加載的作法是,在頁面加載完,鼠標移入以前就經過Image對象把圖片加載進緩存了,這樣鼠標移入的時候直接從緩存裏讀取了,速度很快。
-
圖片預加載:
1234if
(document.images){
var
img =
new
Image();
img.src =
"img/example.jpg"
;
}
-
封裝成一個預加載圖片的函數
123456789101112//實現圖片的預加載
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數組
-
使用一個回調函數來得到圖片的屬性
12345678910111213141516function
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。
- 改進方法:
12345678
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樣式設置一批背景圖片,而後將其隱藏,這樣你就看不到那些圖片了。那些背景圖片就是你想預載的圖片。
1
2
3
|
#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。