利用简洁的图片预加载组件提升H5移动页面的用户体验_前端开发者

在做h5移动页面, 相信大家一定碰到过页面已经打开, 但是里面的图片还未加载出来的情况, 这种问题虽然不影响页面的功能, 但是不利于用户体验。 抛开网速的原因, 解决这个问题有多方面的思路: 最基本的, 要从http请求合并, 缓存管理, 图片压缩等方面做性能优化; 另外就是可以对页面里用到的所有图片做预加载的处理, 当用户打开页面的时候不立即显示第一屏, 而是先显示资源加载效果, 等到加载完毕, 再来显示页面的主内容, 这样就能解决那个问题。 虽然这种加载效果占用了用户的浏览时间, 但是我们可以把它做的好看有趣一点, 所以也不会影响用户体验。 本文实践了这种想法, 提供一个非常简洁的图片预加载组件, 实现简单, 功能不弱, 在做移动页面的时候应该对你有参考价值。 效果( 代码下载): 1. 实现思路html里面的img标签和css中background – imag等都会触发浏览器去加载相关的图片, 但是如果这个图片已经加载过了的话, 浏览器就会直接使用这张已经加载好的图片, 从而能够瞬间在页面中渲染出来。 通过javascript, 创建Image对象, 然后把这些对象的src属性设置成要加载的图片地址也能触发浏览器加载图片, 利用这一点就能实现图片预加载的功能: 在页面里首先把那些用到了相关的图片的元素给藏掉, 然后用js去加载图片, 等到所有图片加载完毕再把藏掉的元素显示即可。 不过这仅仅是一个基本的实现思路, 要完成一个功能较健壮的预加载组件, 还有以下三个问题: 1) 进度问题由于预加载的同时, 还得做一个预加载的效果, 这就需要把加载的进度实时通知到外部上下文才行。 关于进度有两个实现方式, 第一是已加载的数据大小总的数据大小, 第二是已加载的文件数总的文件数, 在浏览器里面, 采用第一种方式是不现实的, 根本没有原生的办法可以做到, 所以只能采用第二种。 2) 图片加载失败的问题比如说有4张图片, 已经加载了50 % ,在加载第三张的时候出错了, 该不该将进度反馈成75 % 呢? 答案是: 应该。 如果不这么处理的话, 进度永远无法到100 % ,页面主内容就没机会显示了, 虽然图片加载有失败的情况, 但是跟加载器没有关系, 也许图片本身就不存在呢? 也就是说图片加载失败不应该影响加载器的功能。 3) 图片加载超时的问题图片不能加载太久, 否则用户一直停留在加载效果上看不到主内容, 用户的等待时间不可控制地延长, 导致用户体验下降, 这样就有悖加载器的初衷了。 所以应该给每个图片设置一个加载的超时时间, 如果在所有图片的超时时间之后, 还没加载完, 就应该主动放弃加载, 通知外部上下文加载完毕, 显示主内容。 综合以上这些需求, 本文提供的实现是:(function () {
functionisArray(obj){
returnObject.prototype.toString.call(obj) ==='[object Array]’;
}***@paramimgList要加载的图片地址列表,[‘aaasd.png’,’aaxxx.png’] *@paramcallback每成功加载一个图片之后的回调, 并传入“ 已加载的图片总数要加载的图片总数” 表示进度*@paramtimeout每个图片加载的超时时间, 默认为5s*
varloader=function(imgList,callback,timeout){
timeout=timeout||5000;
imgList=isArray(imgList) &imgList|| [];
callback=typeof (callback) ===’function’&callback;
vartotal=imgList.length,
loaded=0,
imgages= [],
_on=function(){
loadedtotal));
};
if (!total) {
returncallback&callback(1);
}
for (var i = 0; i) {
imgages[i] =newImage();
imgages[i].onload=imgages[i].onerror=_on;
imgages[i].src=imgList[i];
} ** * 如果timeout * total时间范围内, 仍有图片未加载出来( 判断条件是loaded * setTimeout(function () {
loadedtotal));
}, timeout * total);
};
“function” === typeof define & define.cmd ? define(function () {
return loader
}) : window.imgLoader = loader;
})();
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44(function () {
functionisArray(obj){
returnObject.prototype.toString.call(obj) ==='[object Array]’;
}***@paramimgList要加载的图片地址列表,[‘aaasd.png’,’aaxxx.png’] *@paramcallback每成功加载一个图片之后的回调, 并传入“ 已加载的图片总数要加载的图片总数” 表示进度*@paramtimeout每个图片加载的超时时间, 默认为5s*
varloader=function(imgList,callback,timeout){
timeout=timeout||5000;
imgList=isArray(imgList) &imgList|| [];
callback=typeof (callback) ===’function’&callback;
vartotal=imgList.length,
loaded=0,
imgages= [],
_on=function(){
loadedtotal));
};
if (!total) {
returncallback&callback(1);
}
for (var i = 0; i) {
imgages[i] =newImage();
imgages[i].onload=imgages[i].onerror=_on;
imgages[i].src=imgList[i];
} ** * 如果timeout * total时间范围内, 仍有图片未加载出来( 判断条件是loaded * setTimeout(function () {
loadedtotal));
}, timeout * total);
};
“function” === typeof define & define.cmd ? define(function () {
return loader
}) : window.imgLoader = loader;
})();
使用方式( 对应代码中的test.html): < script src = “..jsimgLoader.js” > < script > < script > imgLoader([‘..imgpage1.jpg’, ‘..imgpage2.jpg’, ‘..imgpage3.jpg’], function (percentage) {
console.log(percentage)
}); < script > 1 2 3 4 5 6 < script src = “..jsimgLoader.js” > < script > < script > imgLoader([‘..imgpage1.jpg’, ‘..imgpage2.jpg’, ‘..imgpage3.jpg’], function (percentage) {
console.log(percentage)
}); < script > 运行结果: 2. demo说明本文开篇给出的效果, 对应的页面是index.html, 关于这个效果还有两个问题需要说明: 1) 它用了之前这篇博客利用轮播原理结合hammer.js实现简洁的滑屏功能介绍的滑屏思路, 并把它的一些逻辑包装在了swipe.js, 对外提供了一个全局变量Swipe, 这个模块有一个init的方法, 以便外部通过调用Swipe.init() 就能初始化滑屏相关的功能, 原来没有提供这个init方法, 在js加载完毕就会初始化滑屏功能, 有了这个init方法就可以把滑屏的逻辑延迟到加载完毕的时候去初始化。 index.html一共引用了5个js: < script src = “jszepto.js” > < script > < script src = “jstransition.js” > < script > < script src = “jshammer.js” > < script > < script src = “jsimgLoader.js” > < script > < script src = “jsswipe.js” > < script > 1 2 3 4 5 < script src = “jszepto.js” > < script > < script src = “jstransition.js” > < script > < script src = “jshammer.js” > < script > < script src = “jsimgLoader.js” > < script > < script src = “jsswipe.js” > < script > 其中imgLoader.js就是前面介绍图片加载器的实现, 前三个js都是为最后一个swipe.js服务的, 感兴趣的可以继续我的博客利用轮播原理结合hammer.js实现简洁的滑屏功能了解相关内容。 不过滑屏不是本文的重点, 不了解swipe.js不会影响理解本文的内容~2) 虽然我在demo中用到了3张比较大的图片, 但是由于在本地环境, 加载速度还是非常快, 所以一开始的时候, 很难看到预加载的效果, 最后只能想办法在每个进度回调之前做一下延迟, 这才可以看到前面gif图片一开始的那个loading效果, 实现方式是: 模拟加载慢的效果
var callbacks = [];
imgLoader([‘imgpage1.jpg’, ‘imgpage2.jpg’, ‘imgpage3.jpg’], function (percentage) {
vari=callbacks.length;
callbacks.push(function () {
setTimeout(function () {
varpercentT=percentage*100;
$(‘#loader__info’).html(‘Loading ‘+ (parseInt(percentT)) +’%’);
$(‘#loader__progress’)[0].style.width =percentT+’%’;
if (percentage==1) {
setTimeout(function () {
$(‘#loader’).remove();
Swipe.init();
}, 600);
}
callbacks[i+1] &callbacks[i+1]();
}, 600);
});
if (percentage==1) {
callbacks[0]();
}
});
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 模拟加载慢的效果
var callbacks = [];
imgLoader([‘imgpage1.jpg’, ‘imgpage2.jpg’, ‘imgpage3.jpg’], function (percentage) {
vari=callbacks.length;
callbacks.push(function () {
setTimeout(function () {
varpercentT=percentage*100;
$(‘#loader__info’).html(‘Loading ‘+ (parseInt(percentT)) +’%’);
$(‘#loader__progress’)[0].style.width =percentT+’%’;
if (percentage==1) {
setTimeout(function () {
$(‘#loader’).remove();
Swipe.init();
}, 600);
}
callbacks[i+1] &callbacks[i+1]();
}, 600);
});
if (percentage==1) {
callbacks[0]();
}
});
在真实环境, 最好还是不要刻意去加这种延迟, 没必要为了让用户看到一个好看有趣的加载效果, 就浪费它不必要的等待时间, 所以真实环境还是应该用下面的代码: imgLoader([‘imgpage1.jpg’, ‘imgpage2.jpg’, ‘imgpage3.jpg’], function (percentage) {
varpercentT=percentage*100;
$(‘#loader__info’).html(‘Loading ‘+ (parseInt(percentT)) +’%’);
$(‘#loader__progress’)[0].style.width =percentT+’%’;
if (percentage==1) {
$(‘#loader’).remove();
Swipe.init();
}
});
1 2 3 4 5 6 7 8 9 imgLoader([‘imgpage1.jpg’, ‘imgpage2.jpg’, ‘imgpage3.jpg’], function (percentage) {
varpercentT=percentage*100;
$(‘#loader__info’).html(‘Loading ‘+ (parseInt(percentT)) +’%’);
$(‘#loader__progress’)[0].style.width =percentT+’%’;
if (percentage==1) {
$(‘#loader’).remove();
Swipe.init();
}
});
3. 注意事项预加载是一种比较常见的实现效果, 但是在使用的时候, 有些问题需要注意: 1) 什么时候用页面大的时候用, 一般页面大小超过3M就该考虑使用; 页面内包含数据量比较大的图片, 在手机端测试能够明显看到加载缓慢的时候, 可以考虑使用。 2) 尽量使用sprite图片3) 加载效果实现的时候, 尽量不用图片, 即使要用也应该用很小的图片, 否则加载效果卡在那就没有意义了。 4. 总结本文主要介绍了一个简单的图片预加载器, 可应用于h5移动页面的开发当中, 在它的思路之下, 如果有必要的话, 还可以对它进行一些改造, 用它来加载其它类型的资源, 比如音频或者视频文件, 毕竟这些类型的DOM对象也都有提供类似Image对象的属性和回调。 与预加载的方式相反的, 还有一种图片懒加载的技术, 现在网上已经有比较好用的jquery插件了, 不过还是很值的去深入了解下它的思路跟实现要点。
» 本文来自:前端开发者 » 《利用简洁的图片预加载组件提升H5移动页面的用户体验_前端开发者》
» 本文链接地址:https://www.rokub.com/2241.html
» 您也可以订阅本站:https://www.rokub.com
赞(0)
64K

评论 抢沙发

评论前必须登录!