對於大量圖片的網站,圖片延遲加載是提升速度和性能的好方法。javascript
目前圖片延遲加載主要分兩大塊,一是觸發加載(根據滾動條位置加載圖片);二是自動預加載(加載完首屏後n秒後自動加載其餘位置的圖片)。大致經常使用的就這兩種。php
這裏介紹第一種方法,根據滾動條手動加載圖片,最初採用的是LazyLoad.js這個現成的小插件,固然本身用jquery本身寫也是很簡單的。html
咱們到LazyLoad網站看看他的工做原理,使用方法:點這裏http://www.neoease.com/lazy-load-jquery-plugin-delay-load-image/java
LazyLoad有是一個傻瓜似的插件,使用至關簡單jquery
首先加入jquery的引用chrome
<script src="jquery.js" type="text/javascript"></script>
<script src="jquery.lazyload.js" type="text/javascript"></script>
而後在須要延遲加載的頁面加入
<script>
$("img").lazyload({
placeholder : "/Content/images/grey.gif",
effect : "fadeIn"
});//延遲那些圖片,能夠本身定義
} |
</script>
<body>
......
@foreach(DataRow dr in Model.Rows){
<img src="http://192.168.0.36:8010/@(dr["fSKC"].ToString()).jpg" onerror="this.src='/Content/images/grey.gif';" />
}
.....
</body>
就這麼簡單就能夠將頁面全部的img給「延遲加載」,其餘效果可參考http://www.neoease.com/lazy-load-jquery-plugin-delay-load-image/後端
瀏覽下咱們的頁面,效果確實可以實現,咱們來看看是否真的實現了?瀏覽器
看到結果,我頓時有種被騙的感受,頁面可見區域顯示4張圖片,那麼URL後臺請求圖片也應該<=4條,但真是的URL請求確是314個項目,很顯而後臺已經所有把圖片加載出來了,而LazyLoad只是給你一個延遲加載的假象!假象!假象!app
爲何會這樣呢?分析下JQuery LazyLoad的源碼ide
能夠看看它的JS源碼,基本原理:
1.更改圖片的src屬性爲orginal屬性,中斷圖片加載。
2.圖片滾動到可視區域後再,再把orginal屬性更改成src屬性,使圖片顯示出來。
懂一點點jQuery的童鞋應該瞭解jQuery的加載機制,它的全部功能代碼都要以下放置:
jQuery(document).ready(function($){ //這句話神馬意思?指頁面DOM加載完成後執行!
//功能代碼加這兒
});
可圖片一開始就有正確src,lazyLoad就算在快也快不過頁面打開的http請求撒~,因此LazyLoad形成了一個延遲加載的假象
還有一點不得不說的是:瀏覽器對圖片的下載加載方式。若是圖片正在下載,而後將其src設置爲另一個,那麼以前的圖片是會當即被abort嗎?全部瀏覽器都是這樣的?若是將src設置爲空(img.src=」),那麼以前的圖片會被abort中止加載嗎?全部瀏覽器都這樣?移除src(removeAttibute(‘src’))呢?
實踐證實,上面疑問的答案是 否,也就是不管你移除src或者重設src,都不能阻止瀏覽器(chrome、ff>4?)下載以前的圖片。因此JS版的lazyload是無心義的。只有先後端配合(頁面輸出前就將img的src設置爲佔位圖),才能真正lazyload。
問題發現了,如何解決呢?根據LazyLoad的思想,方法,咱們事先輸出佔位符,而後經過js判斷滾動位置替換img的src爲真實圖片便可。
擴展後的LazyLoad.js以下:
/*
* Lazy Load - jQuery plugin for lazy loading images
*
* Copyright (c) 2007-2009 Mika Tuupola
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/mit-license.php
*
* Project home:
* http://www.appelsiini.net/projects/lazyload
*
* Version: 1.5.0
*
*/
(function ($) {
$.fn.lazyload =function (options) {
var settings = {
threshold: 0,
failurelimit: 0,
event: "scroll",
effect: "show",
container: window
};
if (options) {
$.extend(settings, options);
}
/* Fire one scroll event per scroll. Not one scroll event per image. */
var elements =this;
if ("scroll"== settings.event) {
$(settings.container).bind("scroll", function (event) {
var counter =0;
elements.each(function () {
if ($.abovethetop(this, settings) ||
$.leftofbegin(this, settings)) {
/* Nothing. */
} elseif (!$.belowthefold(this, settings) &&
!$.rightoffold(this, settings)) {
$(this).trigger("appear");
} else {
if (counter++> settings.failurelimit) {
returnfalse;
}
}
});
/* Remove image from array so it is not looped next time. */
var temp = $.grep(elements, function (element) {
return!element.loaded;
});
elements = $(temp);
});
}
this.each(function () {
var self =this;
//我就把這裏的一段代碼刪除了
/* When appear is triggered load original image. */
$(self).one("appear", function () {
if (!this.loaded) {
$("<img />")
.bind("load", function () {
$(self)
.hide()
.attr("src", $(self).attr("original"))
[settings.effect](settings.effectspeed);
self.loaded =true;
})
.attr("src", $(self).attr("original"));
};
});
/* When wanted event is triggered load original image */
/* by triggering appear. */
if ("scroll"!= settings.event) {
$(self).bind(settings.event, function (event) {
if (!self.loaded) {
$(self).trigger("appear");
}
});
}
});
/* Force initial check if images should appear. */
$(settings.container).trigger(settings.event);
returnthis;
};
/* Convenience methods in jQuery namespace. */
/* Use as $.belowthefold(element, {threshold : 100, container : window}) */
$.belowthefold =function (element, settings) {
if (settings.container === undefined || settings.container === window) {
var fold = $(window).height() + $(window).scrollTop();
} else {
var fold = $(settings.container).offset().top + $(settings.container).height();
}
return fold <= $(element).offset().top - settings.threshold;
};
$.rightoffold =function (element, settings) {
if (settings.container === undefined || settings.container === window) {
var fold = $(window).width() + $(window).scrollLeft();
} else {
var fold = $(settings.container).offset().left + $(settings.container).width();
}
return fold <= $(element).offset().left - settings.threshold;
};
$.abovethetop =function (element, settings) {
if (settings.container === undefined || settings.container === window) {
var fold = $(window).scrollTop();
} else {
var fold = $(settings.container).offset().top;
}
return fold >= $(element).offset().top + settings.threshold + $(element).height();
};
$.leftofbegin =function (element, settings) {
if (settings.container === undefined || settings.container === window) {
var fold = $(window).scrollLeft();
} else {
var fold = $(settings.container).offset().left;
}
return fold >= $(element).offset().left + settings.threshold + $(element).width();
};
/* Custom selectors for your convenience. */
/* Use as $("img:below-the-fold").something() */
$.extend($.expr[':'], {
"below-the-fold": "$.belowthefold(a, {threshold : 0, container: window})",
"above-the-fold": "!$.belowthefold(a, {threshold : 0, container: window})",
"right-of-fold": "$.rightoffold(a, {threshold : 0, container: window})",
"left-of-fold": "!$.rightoffold(a, {threshold : 0, container: window})"
});
})(jQuery);
而後頁面內容咱們作以下修改
@model System.Data.DataTable
@{
ViewBag.Title = "";
Layout = "~/Views/Shared/_Layout.cshtml";
int i = 0;
}
@section head{
<script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script> <script src="/Scripts/lazyload.js" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
$("img").lazyload();
});
</script>
}
<table align="center">
<tr>....
<th>
圖片
</th>....
</tr>
@foreach (System.Data.DataRow dr in Model.Rows)
{
<tr>....
<td>
<img src="/Content/images/grey.gif" original="http://192.168.0.36:8010/@(dr["fSKC"].ToString()).jpg" onerror="this.src='/Content/images/grey.gif';"/>
</td>.....
</tr>
}
</table>
好咱們在看下瀏覽器的請求
本頁的數據量一共300多行,也就是300多個圖片,首次加載下,URL加載的請求只有6個,OK啦。
繼續往下瀏覽頁面,在看看效果
能夠看到,LazyLoad起做用了。
分析下<img src="/Content/images/grey.gif" original="http://192.168.0.36:8010/@(dr["fSKC"].ToString()).jpg" onerror="this.src='/Content/images/grey.gif';" />
首先頁面加載的時候就輸出站位符號grey.gif,因爲全部圖片都同樣,因此URL只會請求一次grey.gif,而original是真實的圖片地址,這個供LazyLoad掩飾加載使用。
本文技術上沒啥東西,主要像代表一個道理,不要被表面現象矇騙!
下載地址:http://files.cnblogs.com/qidian10/LazyLoad.rar
參考文檔:
http://immmmm.com/transformation-jquery-lazyload.html
http://www.popo4j.com/qianduan/transformation_jquery_lazyload_plug.html
http://www.qiqiboy.com/2011/04/12/javascript-and-images-lazyload.html
http://www.neoease.com/lazy-load-jquery-plugin-delay-load-image/