利用简洁的图片预加载组件提升html5移动页面的用户体验 _html5教程技巧
在做h5移动页面,相信大家一定碰到过页面已经打开,但是里面的图片还未加载出来的情况,这种问题虽然不影响页面的功能,但是不利于用户体验。抛开网速的原因,解决这个问题有多方面的思路:最基本的,要从http请求合并,缓存管理,图片压缩等方面做性能优化;另外就是可以对页面里用到的所有图片做预加载的处理,当用户打开页面的时候不立即显示第一屏,而是先显示资源加载效果,等到加载完毕,再来显示页面的主内容,这样就能解决那个问题。虽然这种加载效果占用了用户的浏览时间,但是我们可以把它做的好看有趣一点,所以也不会影响用户体验。本文实践了这种想法,提供一个非常简洁的图片预加载组件,实现简单,功能不弱,在做移动页面的时候应该对你有参考价值。
效果:
1. 实现思路
html里面的img标签和css中background-imag等都会触发浏览器去加载相关的图片,但是如果这个图片已经加载过了的话,浏览器就会直接使用这张已经加载好的图片,从而能够瞬间在页面中渲染出来。通过javascript,创建Image对象,然后把这些对象的src属性设置成要加载的图片地址也能触发浏览器加载图片,利用这一点就能实现图片预加载的功能:在页面里首先把那些用到了相关的图片的元素给藏掉,然后用js去加载图片,等到所有图片加载完毕再把藏掉的元素显示即可。不过这仅仅是一个基本的实现思路,要完成一个功能较健壮的预加载组件,还有以下三个问题:
1)进度问题
由于预加载的同时,还得做一个预加载的效果,这就需要把加载的进度实时通知到外部上下文才行。关于进度有两个实现方式,第一是已加载的数据大小/总的数据大小,第二是已加载的文件数/总的文件数,在浏览器里面,采用第一种方式是不现实的,根本没有原生的办法可以做到,所以只能采用第二种。
2)图片加载失败的问题
比如说有4张图片,已经加载了50%,在加载第三张的时候出错了,该不该将进度反馈成75%呢?答案是:应该。如果不这么处理的话,进度永远无法到100%,页面主内容就没机会显示了,虽然图片加载有失败的情况,但是跟加载器没有关系,也许图片本身就不存在呢?也就是说图片加载失败不应该影响加载器的功能。
3)图片加载超时的问题
图片不能加载太久,否则用户一直停留在加载效果上看不到主内容,用户的等待时间不可控制地延长,导致用户体验下降,这样就有悖加载器的初衷了。所以应该给每个图片设置一个加载的超时时间,如果在所有图片的超时时间之后,还没加载完,就应该主动放弃加载,通知外部上下文加载完毕,显示主内容。
综合以上这些需求,本文提供的实现是:
- (function () {
- function isArray(obj) {
- return Object.prototype.toString.call(obj) === '[object Array]';
- }
- /**
- * @param imgList 要加载的图片地址列表,['aa/asd.png','aa/xxx.png']
- * @param callback 每成功加载一个图片之后的回调,并传入“已加载的图片总数/要加载的图片总数”表示进度
- * @param timeout 每个图片加载的超时时间,默认为5s
- */
- var loader = function (imgList, callback, timeout) {
- timeout = timeout || 5000;
- imgList = isArray(imgList) && imgList || [];
- callback = typeof(callback) === 'function' && callback;
- var total = imgList.length,
- loaded = 0,
- imgages = [],
- _on = function () {
- loaded
- };
- if (!total) {
- return callback && callback(1);
- }
- for (var i = 0; i
- imgages[i] = new Image();
- imgages[i].onload = imgages[i].onerror = _on;
- imgages[i].src = imgList[i];
- }
- /**
- * 如果timeout * total时间范围内,仍有图片未加载出来(判断条件是loaded
- * 目的是避免用户等待时间过长
- */
- setTimeout(function () {
- loaded
- }, timeout * total);
- };
- "function" === typeof define && define.cmd ? define(function () {
- return loader
- }) : window.imgLoader = loader;
- })();
使用方式(对应代码中的test.html):
- script src="../js/imgLoader.js">script>
- script>
- imgLoader(['../img/page1.jpg', '../img/page2.jpg', '../img/page3.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="js/zepto.js">script>
- script src="js/transition.js">script>
- script src="js/hammer.js">script>
- script src="js/imgLoader.js">script>
- script src="js/swipe.js">script>
其中imgLoader.js就是前面介绍图片加载器的实现,前三个js都是为最后一个swipe.js服务的,感兴趣的可以继续我的博客利用轮播原理结合hammer.js实现简洁的滑屏功能了解相关内容。不过滑屏不是本文的重点,不了解swipe.js不会影响理解本文的内容~
2)虽然我在demo中用到了3张比较大的图片,但是由于在本地环境,加载速度还是非常快,所以一开始的时候,很难看到预加载的效果,最后只能想办法在每个进度回调之前做一下延迟,这才可以看到前面gif图片一开始的那个loading效果,实现方式是:
- //模拟加载慢的效果
- var callbacks = [];
- imgLoader(['img/page1.jpg', 'img/page2.jpg', 'img/page3.jpg'], function (percentage) {
- var i = callbacks.length;
- callbacks.push(function(){
- setTimeout(function(){
- var percentT = 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(['img/page1.jpg', 'img/page2.jpg', 'img/page3.jpg'], function (percentage) {
- var percentT = 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插件了,不过还是很值的去深入了解下它的思路跟实现要点,等我有时间去研究研究。同时感谢大家一直以来对脚本之家网站的支持!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

不少用户在玩win10的的一些游戏的时候总是会遇到一些问题,比如说卡屏和花屏等等情况,这个时候我们是可以采用打开directplay这个功能来解决的,而且功能的操作方法也很简单。win10旧版组件directplay怎么安装1、在搜索框里面输入“控制面板”然后打开2、查看方式选择大图标3、找到“程序和功能”4、点击左侧的启用或关闭win功能5、选择旧版这里的勾选上就可以了

Vue是目前最流行的前端框架之一,而VUE3则是Vue框架的最新版本,相较于VUE2,VUE3具备了更高的性能和更出色的开发体验,成为了众多开发者的首选。在VUE3中,使用extends继承组件是一个非常实用的开发方式,本文将为大家介绍如何使用extends继承组件。extends是什么?在Vue中,extends是一个非常实用的属性,它可以用于子组件继承父

Vue是一款非常流行的前端框架,它提供了很多工具和功能,如组件化、数据绑定、事件处理等,能够帮助开发者构建出高效、灵活和易维护的Web应用程序。在这篇文章中,我来介绍如何使用Vue实现一个日历组件。1、需求分析首先,我们需要分析一下这个日历组件的需求。一个基本的日历应该具备以下功能:展示当前月份的日历页面;支持切换到前一月或下一月;支持点击某一天,

H5是指HTML5,是HTML的最新版本,H5是一个功能强大的标记语言,为开发者提供了更多的选择和创造空间,它的出现推动了Web技术的发展,使得网页的交互和效果更加出色,随着H5技术的逐渐成熟和普及,相信它将会在互联网的世界中发挥越来越重要的作用。

Vue怎么通过JSX动态渲染组件?下面本篇文章给大家介绍一下Vue高效通过JSX动态渲染组件的方法,希望对大家有所帮助!

Angular框架中组件的默认显示行为不是块级元素。这种设计选择促进了组件样式的封装,并鼓励开发人员有意识地定义每个组件的显示方式。通过显式设置CSS属性 display,Angular组件的显示可以完全控制,从而实现所需的布局和响应能力。

win10旧版组件是需要用户自己去设置里面打开的,因为很多的组件平时都是默认关闭的状态,首先我们需要进入到设置里面,操作很简单,跟着下面的步骤来就可以了win10旧版组件在哪里打开1、点击开始,然后点击“win系统”2、点击进入控制面板3、再点击下面的程序4、点击“启用或关闭win功能”5、在这里就可以选择你要的打开了

Vue组件实战:分页组件开发介绍在Web应用程序中,分页功能是必不可少的一个组件。一个好的分页组件应该展示简洁明了,功能丰富,而且易于集成和使用。在本文中,我们将介绍如何使用Vue.js框架来开发一个高度可定制化的分页组件。我们将通过代码示例来详细说明如何使用Vue组件开发。技术栈Vue.js2.xJavaScript(ES6)HTML5和CSS3开发环
