今天在突然翻到了以前写的js代码,臃肿得简直不忍直视。
并且在页面加载时,因为html渲染以及js动态加载太多太大的图片导致会有卡顿感,看着都头疼。
当然这个是在我分析后得出的结论。

总体思路
先分析问题所在,再来优化。
在开始优化之前,需要先到网站去分析一下页面卡顿的原因。
于是我打开了浏览器(谷歌内核或者谷歌的),开启调试模式,查看performance,record或者reload都看看。

此处以百度为例。

tiaoshi.png

我当时打开一看scripting都2秒了,好的个乖乖,果断判定是js的问题导致的。

原代码分析

window.onload = function(){
function topbanner(){
var idtop=new Array(
"imgsrc",
"imgsrc",
"imgsrc");
var cdtop=idtop.length;
var ntop=Math.floor(Math.random()*100)%cdtop;
var goidtop=idtop[ntop];
    document.getElementById('imgid').src = goidtop;
}
function gif1(){
var id1=new Array(
"imgsrc",
"imgsrc",
"imgsrc",
"imgsrc");
var cd1=id1.length;
var n1=Math.floor(Math.random()*100)%cd1;
var goid1=id1[n1];
    document.getElementById('gifid').src = goid1;
}
function text1(){
var id=new Array(
"text内容1",
"text内容2",
"text内容3",
"text内容4");
var cd=id.length;
var n=Math.floor(Math.random()*100)%cd;
var goid=id[n];
    document.getElementById('textid').innerHTML = goid;
    document.getElementById('textid').title = goid;
}
..................
.....中间部分省略,反正就是重复函数.....
.............................................
function gif16(){
var id16=new Array(
"imgsrc.gif",
"imgsrc.gif",
"imgsrc.gif",
"imgsrc.gif");
var cd16=id16.length;
var n16=Math.floor(Math.random()*100)%cd16;
var goid16=id16[n16];
    document.getElementById('gifid').src = goid16;
}
function text16(){
var id=new Array(
"text内容",
"text内容",
"text内容",
"text内容");
var cd=id.length;
var n=Math.floor(Math.random()*100)%cd;
var goid=id[n];
    document.getElementById('textid').innerHTML = goid;
    document.getElementById('textid').title = goid;
}
topbanner();
gif1();
text1();
........中间部分省略,因为还是重复..........
gif16();
text16();
}

当时的需求是共有67张照片,其中64张是gif图(单张大小2m左右),3张静态图片(单张大小200k左右)。64段文本(字符串),每段大概10个字左右。
综合起来说,就是想要动态改变单独的一个html页面,只要一刷新就随机显示,总共17个img标签(后16个,每个标签随机抽取4张照片中的一张,只改变img的src属性的值),16个a标签(每个标签的title属性和超链接文本动态改变),当然就用了最笨的方法getElementById;
而且因为希望每个标签随机的内容不与其他标签的冲突和重复,所以就傻傻的写了一堆函数,无限重复,最后写完js发现tm的居然臃肿到有414行。

首次伪优化代码

window.onload = function(){
var rand_img=function (idsrc,idname){
var cdtop=idsrc.length;
var ntop=Math.floor(Math.random()*100)%cdtop;
var goidtop=idsrc[ntop];
var gettu=document.getElementById(idname)
return gettu.src = goidtop;
};
var rand_text = function (textname,idtext){
var cd=textname.length;
var n=Math.floor(Math.random()*100)%cd;
var goid=textname[n];
var gettext=document.getElementById(idtext)
     gettext.innerHTML = goid;
     gettext.title = goid;
};
var xgif = [
['imgrsc','imgrsc','imgrsc'],
['imgrsc.gif','imgrsc.gif','imgrsc.gif','imgrsc.gif'],
.......此处省略14行..........
['imgrsc.gif','imgrsc.gif','imgrsc.gif','imgrsc.gif']
];
var xtextname = [
['text内容','text内容','text内容','text内容'],
['text内容','text内容','text内容','text内容'],
.......此处省略13行........
['text内容','text内容','text内容','text内容']
];
var xidname = ['topbanner','gif1'.......'gif16'];
var xidtext = ['text1','text2'.......'text16'];
var i;
for (i = 0; i < xidname.length; i++)
    {
      rand_img(xgif[i],xidname[i]);
    };
for (i = 0; i < xidtext.length; i++)
    {
      rand_text(xtextname[i],xidtext[i]);
    };
}

只是先将函数写好,然后引入多维数组,用for循环把值传进去,循环执行函数。其实本质上感觉还是一样,但是不可思议的是代码瞬间精简到原来的三分之一,只有70行左右。
然后就跑去测试了,谁知道一测试,发现页面依旧会卡顿,此时才想起要去检查图片的大小和格式。
查完后发现图片存在两个问题:
第一,单张图片占用空间太大。
第二,格式是普通的gif,没有转换成web渐进式的。
所以动手压缩图片,并转换成web渐进式图片(关于这个有机会单独开一篇来说)。
并且此时用的是window.onload,所以我一直都是将js放在head标签内。

最终伪优化
其实就是去掉了window.onload,并且将js引用放到了动态加载标签后的位置。

var rand_img=function (idsrc,idname){
var cdtop=idsrc.length;
var ntop=Math.floor(Math.random()*100)%cdtop;
var goidtop=idsrc[ntop];
var gettu=document.getElementById(idname)
gettu.src = goidtop;
};
var rand_text = function (textname,idtext){
var cd=textname.length;
var n=Math.floor(Math.random()*100)%cd;
var goid=textname[n];
var gettext=document.getElementById(idtext);

     gettext.innerHTML = goid;
     gettext.title = goid;
};
var xgif = [
['imgrsc','imgrsc','imgrsc'],
['imgrsc.gif','imgrsc.gif','imgrsc.gif','imgrsc.gif'],
.......此处省略14行..........
['imgrsc.gif','imgrsc.gif','imgrsc.gif','imgrsc.gif']
];
var xtextname = [
['text内容','text内容','text内容','text内容'],
['text内容','text内容','text内容','text内容'],
.......此处省略13行........
['text内容','text内容','text内容','text内容']
];
var xidname = ['topbanner','gif1'.......'gif16'];
var xidtext = ['text1','text2'.......'text16'];
var i;
for (i = 0; i < xidname.length; i++)
    {
      rand_img(xgif[i],xidname[i]);
    };
for (i = 0; i < xidtext.length; i++)
    {
      rand_text(xtextname[i],xidtext[i]);
    };

为什么要这样更改呢,因为html页面的是从上到下依次渲染,起初我使用window.onload是希望等html页面加载完再来重新渲染,因为平时就是这么干的。否则有时候引用js标签的位置不对,会导致js报错(html页面还没有渲染出来时js也不能动态改变dom)。
但是这次可能是由于要动态改变的东西太多,而且由于我使用的getElementById,导致会出现html页面加载完之后明显卡顿之后,才会重新渲染。
最后就改进成了这个伪优化最终代码,至于为什么是伪优化呢,因为还可以使用getElementsByTagName、getElementsByClassName等更多更简便的方式来,还有图片优化还可以涉及到预加载与缓存。
以后有机会再深入一下吧。


本文由 大古 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。

还不快抢沙发

添加新评论