整理一下从别处学来的一种图片懒加载的方式。
什么是图片懒加载,简单来说就是在web应用中,图片不会一次性全部加载,会在你看到该图片的时候在进行加载。即按需加载。
例如淘宝和京东商城等等app,页面上有大量的图片,当向下滑动的时候,图片会在滑到的时候加载。这是一种webapp的优化模式。
通常来说,在移动端上,一般是用img标签来放置图片,将图片data-src属性指向图片的url地址,然后将data-src的值赋给src属性。这样也可以实现加载图片。
< img src="" data-src="http://img...jpg" id=""/>
但是要进行优化,因此不采用给img标签增加src属性的方式,不用img展示,图片也不采用jpg、png24、png8等格式进行储存,而是用base64字符编码串保存到本地缓存localStorage中。这样下次打开网页的时候就可以直接读取缓存不必进行HTTP请求。
将img标签的data-src的值赋给canvas,然后将canvas添加到img标签后面,接下来将img节点删掉,用canvas将图画出来。
canvas支持硬件加速,当图片比较多的时候,列表(如果是列表格局)的性能也比较高。
具体原理是:
具体代码:
// 缓存图片,并将图片渲染
var renderCvs = function(parent,max){
//将img标签的class设置为lazyload,其父节点是a标签
var lazyloadImage = $('.lazyload',parent);
if(lazyloadImage.length<1){
return;
}
var max = max||lazyloadImage.length;
for(var i=0;i<max;i++){
var imgId = lazyloadImage[i].id;
//再次打开网页,读取缓存,如果有,就从缓存中展示
var imageCache = localStorage.getItem(imgId);
if(imageCache){
lazyloadImage[i].src = imageCache;
continue;
}
var img = new Image();
img.index = i;
img.id = imgId;
img.crossorigin="anonymous";
img.onload = function(){
var _this = this;
var zCvs = $('#'+this.id);
var domCvs = zCvs[0];
domCvs.src = this.src;
zCvs.removeClass('lazyload');
try{
var cvs = document.createElement('canvas');
cvs.style.display = 'none';
document.body.appendChild(cvs);
var rcvs = cvs.getContext('2d');
cvs.width = 140;
cvs.height = 108;
rcvs.drawImage(this,0,0,140,108);
//这里进行缓存 ,toDataURL()方法将url转成base64字符串
setTimeout(function(){
var data = cvs.toDataURL();
//将字符串保存到localStorage中
localStorage.setItem(_this.id,data);
document.body.removeChild(cvs);
},200);
}catch(ex){
}
}
img.src = lazyloadImage[i].getAttribute('data-src');
}
}
有问题请直接评论或者联系我。
补充:
有位大哥指出,上述所说的懒加载方法是没有问题的,但是缓存方式有问题。localStorage有大小限制,5M,经过base64位编码,字符串扩大30%,容易超过容量。而且用户可能删除localStorage,容灾方式尚未解决。
所以建议直接使用浏览器自带的缓存,不使用localStorage