前言:lazyload是一个懒加载的基于jquery的懒加载的库。
实现原理:实现原理是在当图片不在视图区域内时,用一个class lazy标识图片,先将该图片的src置为空,把真正的url放到一个自定义属性里面。当检测到该图片需要被展示时,获取自定义属性里真正的url,修改到src里面,实现图片的懒加载。
基于lazyload的实现原理,写了一个demo。以下为代码分析:
缺省配置:
var default_settings = {
event: 'scroll',
failure_limit: 0,
effect: 'show',
container: window,
data_attribute: 'original',
skip_invisible: false,
load: null,
appear: null,
placehold: './placeholder.png'
}
构造器部分:
function lazyLoad(elements,options){
this.$elems = $(elements);
this.settings = $.extend({},options,default_settings);
this.$container = (this.settings.container == 'window'|| this.settings.container == undefined) ? $(window) : $(this.settings.container);
var that = this;
$.each(this.$elems,function(){
var $elem = $(this);
$elem.loaded = false;
console.log($elem[0].id + " " +$elem.loaded);
if($elem.attr("src") == undefined || $elem.attr("src") == false){
if($elem.is("img")){
$elem.attr("src",that.settings.placehold);
}
}// 没加载的实现现实缺省图片
$elem.one("appear",function(){
if(!this.loaded){
var $pic = $(this);
var original_url = $pic.attr("data-" + that.settings.data_attribute);
//
$pic.hide();
if($pic.is("img")){
console.log(original_url);
$pic.attr("src",original_url);
}else{
$pic.src("background_image",original_url);
}
$pic.show();
this.loaded = true;
var temp = $.grep(that.$elems,function(elem){
return !elem.loaded;
});
that.$elems = $(temp);
$(this).removeClass("lazy");
}
});//.attr("src",that.settings.placehold);
});
var that = this;
if(this.settings.event.indexOf('scroll') !== 0){
this.$container.on(this.settings.event,function(){
update(that);
})
}
$(document).ready(function(){
update(that);
})
}
update函数做的事情主要时,检测图片元素的方位跟container的关系。如果在视图上方上下左右之外,不做操作。否则触发appear事件,展示图片。
function update(context){
var count = 0,
that = context;
$.each(that.$elems,function(elem){
var $this = $(this);
if(that.settings.skip_invisible || $this.loaded){
return ;
}
if(that.aboveTheTop($this) || that.leftOfBegin($this)){
}else if(!that.belowTheFold($this) && !that.rightOfEnd($this)){
$this.trigger("appear");
count = 0;
}else{
if(++count > that.settings.failure_limit){
return false;
}
}
});
if(that.settings.event.indexOf('scroll') == 0){
that.$container.on('scroll',function(){
update(that);
})
}
}
定义四个原型方法,用于确定图片和container的方位。其原理是获取container的offset,于图片的offset + 尺寸 做比较。
完整代码:https://github.com/lizzyDeng/lazyload
性能测试:
测试demo。一共两组实验,一组的图片数据量较小,为30张。一组为数据量大一些,为200张。一组对照组中,一个用普通的图片加载,一个使用懒加载。测试数据如下:
小数据量对照组(关注load+script的时间):
normal-load:load:2.5ms,scripting:32.2ms
lazy-load: load:1.8ms,script:148.8ms
结论:加载速度提升一倍,但是script的增加了4.6倍
大数据量对照组(loadTime+scripintTime)
normal-load:load:8.1ms,script:51.1ms
lazy-load:load:2.6ms,script:315.6ms
load时间提升4倍,然而script时间提升了6倍。感想:在数据量越大的时候,lazyload的优势越大。对于script时间的增加,由于测试normal组的demo里面并没有任何js的执行,所以在实际环境中,可能script的影响不会着么大。