图册组件优化之路(一)
根据六马系统需要,写了一个图册组件,方便给编辑器添加图册显示使用。
效果可以参考这里:http://game.163.com/2016/chinajoy/2016/07/29/22769_632281.html
匆忙发布了第一个版本出去,发现编辑们流行图册都发一两百张图上去的,由于没有做加载优化,导致问题很明显,一开始需要请求双倍的图片总数请求,页面存在多个图册,打开就会加载得很慢才出来,好多菊花满屏转
一、代码按需加载
图册兼容PC和移动两个web端,一般情况下,都是代码写一块,根据参数或者终端类型判断,来运行对应的代码
这样方式存在以下问题:
- 一个页面基本是不会存在同时加载PC和移动端两种图册
- 调用一端图册,需要把另外一端的CSS、JS、模板都加载了
- 双端的代码会存在比较多的耦合性
按需要加载文件的方式(以下是简易代码)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | //pc.js var PC = function (param){} //m.js var M = function (param){} //main.js var Main = function (param){ //判断当前是移动端还是PC端 var isMoible = /android|ios|iphone/i.test(navigator.userAgent); //加载对应的文件 if (isMoible){ //假设已经实现了加载文件的方法load,加载成功后就调用M load( "m.js" , function (){M(param)}); } else { load( "pc.js" , function (){PC(param)}); } } |
加载css和模板,跟上面的类似,一并进行加载,不过使用这种方式会存在以下问题(需要自行权衡来使用):
- 会需要写多一个入口文件,去按需加载文件,比如上面的:
main.js
- 由于是异步加载
pc.js
和m.js
,所以不方便由main.js
提供接口出来给外部使用 - 代码量不多的时候,不推荐这么使用,反而更麻烦了
二、图片按需加载
图册多则能上两百张以上,大图小图一起加载,则会变成双倍图片一起请求,加载量可想而知会很多,大量请求堵塞,使得图册加载很慢,所以图片按需加载显得非常重要,一般我们会比较常用
lazyload
这个插件来完成,不过其实没必要,自己也能简易实现
1、滚动按需加载
监听滚动条的滚动事件,判断所有图片的位置是否在可视区域内,如果是,则加载此图片出来
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 | //延时计时器ID var scrollTimeId = 0; //相册容器 var testDom = document.getElementById( "test" ); //绑定滚动事件 testDom.onscroll = function (){ //每一次滚动都清空上一次的计时器事件,避免用户快速滚动不断调用问题 clearTimeout(scrollTimeId); //延迟200ms执行事件,基本为用户滚动停止后才会触发 scrollTimeId = setTimeout( function (){ //获取所有的图片 var imgList = testDom.getElementsByTagName( "img" ); //获取容器的滚动位置(相册为左右滚动,所有获取Left) var scrollLeft = testDom.scrollLeft; var scrollRight = testDom.offsetWidth + scrollLeft; //遍历图片列表 for ( var i=0,l=imgList.length;i<l;i++){ var img = imgList[i]; var imgLeft = img.offsetLeft; var imgRight = img.offsetWidth + imgLeft; //判断图片是否在当前滚动的可视区域内 if ((imgLeft >= scrollLeft && imgLeft <= scrollRight) || (imgRight > scrollLeft && imgRight < scrollRight)){ //加载图片,一般真实地址在data-src属性中 img.src = img.getAttribute( "dat-src" ); } } },200); } |
2、点击切换按需加载
图册的大图为用户点击按钮进行切换,最省流量方式为,用户点击哪张我才加载哪张,但这样用户会每次切换都出现加载中的提示,比较不友好,所以改进一下方式,帮用户预加载前后各两张图,减少出现加载提示的几率
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | function loadImg(index){ //假设图册有10张图 var max = 10; //保存要加载的图的索引列表 var load = []; //图片列表 var imgList = document.getElementsByTagName( "img" ) //默认添加当前位置的图片 load.push(index); //判断前后两张图的位置是否合法,合法则添加进去 if (index - 1 > 0)load.push(index-1); if (index - 2 > 0)load.push(index-1); if (index + 1 < max)load.push(index+1); if (index + 2 < max)load.push(index+2); //遍历索引列表,设置图片加载 for ( var i=0;i<load.length;i++){ img[index].src = img[index].getAttribute( "dats-src" ); } } |
PS:还有性能和内存优化这块没做,下一步会去优化这块的事情
手机阅读请扫描下方二维码:
12345678

1
1
1
1
1
1
1
1
1
1
1
12345678

nxygzqiylyeplpudtsiv
12345678

12345678

12345678

12345678

1

1

1

1

1

1

1

1

1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1