背景
当前各种网站图片的大量使用很大程度上丰富了网站内容,方便了人们阅读,但与之而来的大量图片的使用,在网站加载时增加了负担,如果不能很好的及时有效的加载这些图片,会造成图片展示不全或不展示等一系列用户体验不好的问题。从而会降低用户对整体网站的体验度。进而针对图片的优化,有很多的解决方案。这篇主要讨论的是图片预加载方案。
“预加载”顾名思义就是事先加载,它预判用户可能的操作,事先加载好可能浏览的图片,从而在用户正真访问时从缓存中快速访问,达到快速流畅的效果。而预加载分为两类,有序加载和无序加载。
无序加载
无序加载就是加载时不考虑图片的加载顺序往往是一次性的加载可能访问的图片,适用的场景比如图片册等。代码如下:
function unordered(imgs){
let len = imgs.length;
for (let i = 0; i < len; i++) {
let imgObj = new Image(); // 创建图片对象
imgObj.src = imgs[i];
$(imgObj).on('load error', function () {
console.log('imgs' + i + '加载完毕');
});
}
}
有序加载
有序加载与无序加载对应的是加载时需要考虑图片的加载顺序,必须在前一张加载完成之后再加载下一张,比如漫画网站,在浏览漫画时,漫画的每一页都是有顺序的,必须要按照页数来顺序加载。代码如下
function ordered(imgs) {
let count = 0;
var imgObj = new Image();
imgObj.src = imgs[count];
let len = imgs.length;
$(imgObj).on('load error', function () {
if (count >= len) {
console.log('全部加载完毕');
} else {
load(); // 加载下一张
}
count++;
});
}
总结
图片预加载的核心思想就是“未雨绸缪”,在还未浏览到可能浏览的图片时,利用当前浏览的空闲时间去加载后面的图片,在加载的时候可能会用AJAX的异步请求的技术,但只要搞清楚它的原理,只是修改它的加载方式就很easy啦。
下面附上完整预加载插件代码(该插件代码需先引入jquery)
(function($) {
function Preload(imgs, options) {
this.imgs = (typeof imgs === "string") ? [imgs] : imgs;
this.options = $.extend({}, Preload.DEFAULTS, options)
if (this.options.order === "unordered") {
this._unordered();
} else {
this._ordered();
}
}
Preload.DEFAULTS = {
order: "unordered",
each: null, //每加载一个图片完毕执行
all: null //所有图片加载完毕后执行
};
Preload.prototype._ordered = function() {
if (typeof src != "string") {
return;
}
var count = 0,
imgs = this.imgs,
options = this.options;
function load() {
var imgObj = new Image();
$(imgObj).on("load error", function() {
options.each && options.each();
if (count >= imgs.length - 1) { //判断是否加载完毕
options.all && options.all();
} else {
load(); //加载下一张
}
});
imgObj.src = imgs[count];
count++;
}
};
Preload.prototype._unordered = function() {
var count = 0,
imgs = this.imgs,
options = this.options;
$.each(imgs, function(i, src) {
if (typeof src != "string") {
return;
}
var imgObj = new Image();
$(imgObj).on("load error", function() {
options.each && options.each(count);
if (count >= imgs.length - 1) { //判断是否加载完毕
options.all && options.all();
}
count++
});
imgObj.src = src;
});
};
$.extend({
preload: function(imgs, opts) {
new Preload(imgs, opts);
}
})
})(jQuery);