Js优化适用于IE6.0,总结以下几点:一、字符串拼接:用数组拼接复制代码如下: func 2()函数{var start=newdate()。gettime();var数组=[];for(var I=0;我10000;i ){数组[i]='输入类型='按钮'值=' a} 2.for循环:首先计算长度,直接调用copy代码如下: func 2(){ vardivs=document . getelementsbyname(' div ');var start=新日期()。getTime();for(var i=0,len=div s . length;我透镜;I ){ //'高效率' }第三,减少页面的重绘:可以把页面拼接在一起,然后给页面赋值。复制代码如下: func 2(){ varobj=document . getelementbyid(' demo ');var start=新日期()。getTime();var arr=[];for(var I=0;i 100I){ arr[I]=str I;} obj . innerhtml=arr . join(');第四,减少范围链上的搜索次数:如果取多个页面值,定义一个document对象,然后调用这个对象复制代码如下:var doc=documentfor(var I=0;我10000;I){ var but 1=doc . getelementbyid(' but 1 ');var but 2=doc . getelementbyid(' but 2 ');var inputs=doc . getelementsbytagname(' input ');}} 5.避免双重解释:不要重复调用函数或方法。1.字符串拼接。字符串拼接是我们开发中经常遇到的,所以我先放一放。我们习惯于用=直接拼接字符串。其实这种拼接方式效率很低。我们可以用一种巧妙的方法来实现字符串拼接,即使用数组的连接方法。复制的代码如下: div class=' one ' id=' one '/div input type=' button '值=' Low efficiency ' onclick=' func 1()'/input type=' button '值=' high efficiency ' onclick=' func 2()'///Low efficiency func 1(){ var start=new date()。gettime();var模板=' ';for(var I=0;我10000;i ){ template='input type='button '值=' a} var end=新日期()。getTime();document.getElementById('one ')。innerHTML=模板;Alert('耗时: '(结束-开始)'毫秒');}//高效function func 2(){ var start=new date()。gettime();var数组=[];for(var I=0;我10000;i ){数组[i]='输入类型='按钮'值=' a} var end=新日期()。getTime();document.getElementById('one ')。innerHTML=array . join(“”);Alert('耗时: '(结束-开始)'毫秒');}我们来看看它在不同浏览器下的执行情况。
我们会发现在IE6下差别还是挺明显的,在IE的更高版本也非常明显,但是在Firefox下差别不大。相反,第二款的相对效率更低,但差别只有2ms左右,Chrome和Firefox差不多。顺便说一下,当我们向数组中添加元素时,许多人喜欢使用数组推送的本机方法。事实上,直接使用arr[i]或arr[arr.length]更快。在10000个周期的情况下,IE浏览器会有十几毫秒的差异。2.for循环是我们经常遇到的情况。我们来看看下面的例子:复制代码如下: input type=' button ' value=' low efficiency ' onclick=' func 1()'/input type=' button ' value=' high efficiency ' onclick=' func 2()'/vararr=[。for(var I=0;我10000;I){ arr[I]=' div ' I '/div ';} document . body . innerhtml=arr . join(');//低效function func 1(){ vardivs=document . getelementsbytagname(' div ');var start=新日期()。getTime();for(var I=0;i divs.lengthI ){ //'低效' } var end=new Date()。getTime();Alert ('time:' (end-start)'毫秒');}//高效function func 2(){ vardivs=document . getelementsbytagname(' div ');var start=新日期()。getTime();for(var i=0,len=div s . length;我透镜;I ){ //'高效' } var end=new Date()。getTime();Alert ('time:' (end-start)'毫秒');}
从上表可以看出,在IE6.0下,差别非常明显,而在Firefox和Chrome下,差别几乎没有。之所以在IE6.0下会出现这种情况,是因为在for循环的执行过程中,第一种情况每次都会计算长度,而第二种情况会在开始的时候计算长度并保存在变量中,所以它的执行效率会更高,所以当我们使用for循环时,尤其如此。但不是只要我们取长度,就会有这么明显的区别。如果我们只操作一个数组,得到一个数组的长度,那么这两种方法在写法上其实是相似的。我们来看下面的例子:复制代码如下: input type=' button ' value=' low efficiency ' onclick=' func 1()'/input type=' button ' value=' high efficiency ' onclick=' func 2()'/var arr 2=[];for(var I=0;我10000;I){ arr 2[I]=' div ' I '/div ';}//低效function func 1(){ var start=new date()。gettime();for(var I=0;长度;I ){ //'低效' } var end=new Date()。getTime();Alert ('time:' (end-start)'毫秒');}//高效function func 2(){ var start=new date()。gettime();for(var i=0,len=arr 2 . length;我透镜;I ){ //'高效' } var end=new Date()。getTime();Alert ('time:' (end-start)'毫秒');}
从上表可以看出,如果只是一个数组,可以看出两种写法几乎是一样的。事实上,如果我们将循环调整到10万次,差异只有几毫秒,所以在数组的情况下,我认为它们都是一样的。对于For循环的优化,有人提出了很多观点。有人认为完全没有必要用-=1,或者从大到小循环等等。在实际情况中,这些优化往往根本没有显示出来。换句话说,它们只是计算机层面的微小变化,但却给我们带来了代码可读性的极大降低,因此不值得去做。3.减少页面重绘减少页面重绘虽然本质上不是JS本身的优化,但往往是JS造成的,重绘往往严重影响页面性能,所以拿出来绝对有必要。我们来看下面的例子:复制的代码如下: div id=' demo '/div input type=' button '值=' low efficiency ' onclick=' func 1()'/input type=' button '值=' high efficiency ' onclick=' func 2()'/Var str=' div这是测试字符串/divdiv这是测试字符串/divdiv这是测试字符串/divdiv这是测试字符串/divdiv divDiv这是测试字符串/divdiv这是测试字符串/divdiv这是测试字符串/divdiv这是测试字符串/divdiv这是测试字符串/div ';//低效function func 1(){ varobj=document . getelementbyid(' demo ');var start=新日期()。getTime();for(var I=0;i 100I){ obj . innerhtml=str I;} var end=新日期()。getTime();警报('结束-开始''毫秒');}//高效function func 2(){ varobj=document . getelementbyid(' demo ');var start=新日期()。getTime();var arr=[];for(var I=0;i 100I){ arr[I]=str I;} obj . innerhtml=arr . join(');var end=新日期()。getTime();警报('结束-开始''毫秒');}在示例中,我只使用了100个周期,因为如果我使用了10000个周期,浏览器基本上会被卡住,但即使是100个周期,我们来看看下面的执行结果。
可以看出,这是一个惊人的结果。仅仅过了100个周期,不管什么浏览器,都有这么大的区别。此外,我们还发现IE6的执行效率要比Firefox好很多,这说明Firefox在页面重绘方面没有做一些优化。这里还需要注意的是,一般影响页面重绘的不仅仅是innerHTML,如果元素的样式和位置发生变化,也会触发页面重绘,所以平时一定要注意这一点。
4、减少作用域链上的查找次数我们知道,js代码在执行的时候,如果需要访问一个变量或者一个函数的时候,它需要遍历当前执行环境的作用域链,而遍历是从这个作用域链的前端一级一级的向后遍历,直到全局执行环境,所以这里往往会出现一个情况,那就是如果我们需要经常访问全局环境的变量对象的时候,我们每次都必须在当前作用域链上一级一级的遍历,这显然是比较耗时的,我们看下面的例子:复制代码代码如下:div id='demo'/div输入id=' but 1 ' type=' button ' onclick=' func 1()' value='效率低/input id=' but 2 ' type=' button ' onclick=' func 2()' value='效率高功能1函数(){ var start=new Date().getTime();for(var I=0;我10000;I){ var but 1=文档。getelementbyid('但不是1 ');var但2=文档。getelementbyid('但不是2 ');var输入=文档。getelementsbytagname(' input ');var divs=文档。getelementsbytagname(' div ');var但1=文档。getelementbyid('但不是1 ');var但2=文档。getelementbyid('但不是2 ');var输入=文档。getelementsbytagname(' input ');var divs=文档。getelementsbytagname(' div ');var但1=文档。getelementbyid('但不是1 ');var但2=文档。getelementbyid('但不是2 ');var输入=文档。getelementsbytagname(' input ');var divs=文档。getelementsbytagname(' div ');var但1=文档。getelementbyid('但不是1 ');var但2=文档。getelementbyid('但不是2 ');var输入=文档。getelementsbytagname(' input ');var divs=文档。getelementsbytagname(' div ');var但1=文档。getelementbyid('但不是1 ');var但2=文档。getelementbyid('但不是2 ');var输入=文档。getelementsbytagname(' input ');var divs=文档。getelementsbytagname(' div ');var但1=文档。getelementbyid('但不是1 ');var但2=文档。getelementbyid('但不是2 ');var输入=文档。getelementsbytagname(' input ');var divs=文档。getelementsbytagname(' div ');} var end=新日期()。getTime();警报('用时(结束-开始)毫秒');}函数func2(){ var start=new Date().getTime();var doc=文档;for(var I=0;我10000;I){ var但是1=doc。getelementbyid('但不是1 ');var但2=doc。getelementbyid('但不是2 ');var输入=doc。getelementsbytagname(' input ');var div s=doc。getelementsbytagname(' div ');var但1=doc。getelementbyid('但不是1 ');var但2=doc。getelementbyid('但不是2 ');var输入=doc。getelementsbytagname(' input ');var div s=doc。getelementsbytagname(' div ');var但1=doc。getelementbyid('但不是1 ');var但2=doc。getelementbyid('但不是2 ');var输入=doc。getelementsbytagname(' input ');var div s=doc。getelementsbytagname(' div ');var但1=doc。getelementbyid('但不是1 ');var但2=doc。getelementbyid('但不是2 ');var输入=doc。getelementsbytagname(' input ');var div s=doc。getelementsbytagname(' div ');var但1=doc。getelementbyid('但不是1 ');var但2=doc。getelementbyid('但不是2 ');var输入=doc。getelementsbytagname(' input ');var div s=doc。getelementsbytagname(' div ');var但1=doc。getelementbyid('但不是1 ');var但2=doc。getelementbyid('但不是2 ');var输入=doc。getelementsbytagname(' input ');var div s=doc。getelementsbytagname(' div ');} var end=新日期()。getTime();警报('用时(结束-开始)毫秒');} 上面代码中,第二种情况是先把全局对象的变量放到函数里面先保存下来,然后直接访问这个变量,而第一种情况是每次都遍历作用域链,直到全局环境,我们看到第二种情况实际上只遍历了一次,而第一种情况却是每次都遍历了,所以我们看看其执行结果
从上表可以看出,在IE6下差异还是非常明显的,在多级范围链和多个全局变量的情况下差异会非常明显。5.我们经常会遇到避免双重解读的情况。有时候我们不认为这种情况会影响效率。当我们使用eval、new Function和setTimeout时,通常会遇到双重解释。我们来看下下面的例子:复制代码如下: div id=' demo '/div input id=' but 1 ' type=' button ' onclick=' func 1()' value=' low efficiency '/input id=' but 2 ' type=' but ' but ' but ' but ' onclick=' func 2()' value。函数func1(){ var start=new Date()。getTime();for(var I=0;我10000;i ){ var func=新函数(' sum=num1num1=num2' num2');func();} var end=新日期()。getTime();警报('结束-开始''毫秒');}函数func2(){ var start=new Date()。getTime();for(var I=0;我10000;I){ sum=num 1;num1=num2num2} var end=新日期()。getTime();警报('结束-开始''毫秒');}在第一种情况下,我们使用新的Function进行双重解释,第二种情况是避免双重解释。我们来看看不同浏览器下的性能:。
可以看出,在所有浏览器中,双重解释的代价都很高,所以在实践中,应该尽可能避免双重解释。感谢‘seasonk’对第四次测试报告中的错误进行了修正,现在已经修改了。至于最后一点,func1每次都是初始化的,没有可比性,所以我改了eval,发现在IE6.0下还是有影响的,在Firefox下,使用eval对效率的影响更严重。在Firefox下,如果有10000个周期,需要十几秒,所以我把周期改成了1000个。看代码和报告。复制代码如下:var sum,num1=1,num2=2函数func1(){ var start=new Date()。getTime();for(var I=0;i 1000I){ eval(' sum=num 1;num1=num2' num2');} var end=新日期()。getTime();警报('结束-开始''毫秒');}函数func2(){ var start=new Date()。getTime();for(var I=0;i 1000I){ sum=num 1;num1=num2num2} var end=新日期()。getTime();警报('结束-开始''毫秒');}