图册组件优化之路(一)
根据六马系统需要,写了一个图册组件,方便给编辑器添加图册显示使用。
效果可以参考这里:http://game.163.com/2016/chinajoy/2016/07/29/22769_632281.html
匆忙发布了第一个版本出去,发现编辑们流行图册都发一两百张图上去的,由于没有做加载优化,导致问题很明显,一开始需要请求双倍的图片总数请求,页面存在多个图册,打开就会加载得很慢才出来,好多菊花满屏转
一、代码按需加载
图册兼容PC和移动两个web端,一般情况下,都是代码写一块,根据参数或者终端类型判断,来运行对应的代码
这样方式存在以下问题:
- 一个页面基本是不会存在同时加载PC和移动端两种图册
- 调用一端图册,需要把另外一端的CSS、JS、模板都加载了
- 双端的代码会存在比较多的耦合性
按需要加载文件的方式(以下是简易代码)
//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、滚动按需加载
监听滚动条的滚动事件,判断所有图片的位置是否在可视区域内,如果是,则加载此图片出来
//延时计时器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、点击切换按需加载
图册的大图为用户点击按钮进行切换,最省流量方式为,用户点击哪张我才加载哪张,但这样用户会每次切换都出现加载中的提示,比较不友好,所以改进一下方式,帮用户预加载前后各两张图,减少出现加载提示的几率
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
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