javascript系列---如何优化js

1、字符串的拼接

 字符串的拼接在我们开发中会经常遇到,所以我把其放在首位,我们往往习惯的直接用+=的方式来拼接字符串,其实这种拼接的方式效率非常的低,我们可以用一种巧妙的方法来实现字符串的拼接,那就是利用数组的join方法。

 
 
  1. <div class="one" id="one"></div>   
  2. <input type="button" value="效率低" οnclick="func1()" />   
  3. <input type="button" value="效率高" οnclick="func2()" /> 
 
 
  1. //效率低的   
  2. function func1(){   
  3.     var start = new Date().getTime();   
  4.     var template = "";   
  5.     for(var i = 0; i < 10000; i++){   
  6.         template += "<input type='button' value='a'>";   
  7.     }   
  8.     var end = new Date().getTime();   
  9.     document.getElementById("one").innerHTML = template;   
  10.     alert("用时:" + (end - start) + "毫秒");   
  11. }   
  12. //效率高的   
  13. function func2(){   
  14.     var start = new Date().getTime();   
  15.     var array = [];   
  16.     for(var i = 0; i < 10000; i++){   
  17.         array[i] = "<input type='button' value='a'>";   
  18.     }   
  19.     var end = new Date().getTime();   
  20.     document.getElementById("one").innerHTML = array.join("");   
  21.     alert("用时:" + (end - start) + "毫秒");   
  22. }   

2、for循环

for循环是我们经常会遇到的情况,我们先看看下面例子:

 
 
  1. <input type="button" value="效率低" οnclick="func1()" />   
  2. <input type="button" value="效率高" οnclick="func2()" /> 
 
 
  1. var arr = [];   
  2. for(var i = 0; i < 10000; i++){   
  3.     arr[i] = "<div>" + i + "</div>";   
  4. }   
  5. document.body.innerHTML += arr.join("");   
  6.     
  7. //效率低的   
  8. function func1(){   
  9.     var divs = document.getElementsByTagName("div");   
  10.     var start = new Date().getTime();   
  11.     for(var i = 0; i < divs.length; i++){   
  12.         //"效率低"   
  13.     }   
  14.     var end = new Date().getTime();   
  15.     alert("用时:" + (end - start) + "毫秒");   
  16. }   
  17. //效率高的   
  18. function func2(){   
  19.     var divs = document.getElementsByTagName("div");   
  20.     var start = new Date().getTime();   
  21.     for(var i = 0, len = divs.length; i < len; i++){   
  22.         //"效率高"   
  23.     }   
  24.     var end = new Date().getTime();   
  25.     alert("用时:" + (end - start) + "毫秒");   

主要是因为for循环在执行中,第一种情况会每次都计算一下长度,而第二种情况却是在开始的时候计算长度,并把其保存到一个变量中,所以其执行效率要高点,所以在我们使用for循环的时候,特别是需要计算长度的情况,我们应该开始将其保存到一个变量中。但是并不是只要是取长度都会出现如此明显的差别,如果我们仅仅是操作一个数组,取得的是一个数组的长度,那么其实两种方式的写法都差不多,我们看下面的例子:

 
 
  1. <input type="button" value="效率低" οnclick="func1()" />   
  2. <input type="button" value="效率高" οnclick="func2()" />  
 
 
  1. var arr2 = [];   
  2. for(var i = 0; i < 10000; i++){   
  3.     arr2[i] = "<div>" + i + "</div>";   
  4. }   
  5. //效率低的   
  6. function func1(){   
  7.     var start = new Date().getTime();   
  8.     for(var i = 0; i < arr2.length; i++){   
  9.         //"效率低"   
  10.     }   
  11.     var end = new Date().getTime();   
  12.     alert("用时:" + (end - start) + "毫秒");   
  13. }   
  14. //效率高的   
  15. function func2(){   
  16.     var start = new Date().getTime();   
  17.     for(var i = 0, len = arr2.length; i < len; i++){   
  18.         //"效率高"   
  19.     }   
  20.     var end = new Date().getTime();   
  21.     alert("用时:" + (end - start) + "毫秒");   

3、减少页面的重绘

减少页面重绘虽然本质不是JS本身的优化,但是其往往是由JS引起的,而重绘的情况往往是严重影响页面性能的,所以完全有必要拿出来,我们看下面例子:

 
 
  1. <div id="demo"></div>   
  2. <input type="button" value="效率低" οnclick="func1()" />   
  3. <input type="button" value="效率高" οnclick="func2()" /> 
 
 
  1. var str = "<div>这是一个测试字符串</div><div>这是一个测试字符串</div><div>这是一个测试字符串</div><div>这是一个测试字符串</div><div>这是一个测试字符串</div><div>这是一个测试字符串</div><div>这是一个测试字符串</div><div>这是一个测试字符串</div><div>这是一个测试字符串</div><div>这是一个测试字符串</div><div>这是一个测试字符串</div><div>这是一个测试字符串</div><div>这是一个测试字符串</div>";   
  2. //效率低的   
  3. function func1(){   
  4.     var obj = document.getElementById("demo");   
  5.     var start = new Date().getTime();   
  6.     for(var i = 0; i < 100; i++){   
  7.         obj.innerHTML += str + i;   
  8.     }   
  9.     var end = new Date().getTime();   
  10.     alert("用时 " + (end - start) + " 毫秒");   
  11. }   
  12. //效率高的   
  13. function func2(){   
  14.     var obj = document.getElementById("demo");   
  15.     var start = new Date().getTime();   
  16.     var arr = [];   
  17.     for(var i = 0; i < 100; i++){   
  18.         arr[i] = str + i;   
  19.     }   
  20.     obj.innerHTML = arr.join("");   
  21.     var end = new Date().getTime();   
  22.     alert("用时 " + (end - start) + " 毫秒");   

在例子中,我只是用了100次的循环,因为如果用10000次循环的话,浏览器基本上就卡住不动

4、减少作用域链上的查找次数

我们知道,js代码在执行的时候,如果需要访问一个变量或者一个函数的时候,它需要遍历当前执行环境的作用域链,而遍历是从这个作用域链的前端一级一级的向后遍历,直到全局执行环境,所以这里往往会出现一个情况,那就是如果我们需要经常访问全局环境的变量对象的时候,我们每次都必须在当前作用域链上一级一级的遍历,这显然是比较耗时的,我们看下面的例子:

 
 
  1. <div id="demo"></div>   
  2. <input id="but1" type="button" οnclick="func1()" value="效率低"/>   
  3. <input id="but2" type="button" οnclick="func2()" value="效率高"/>   
  4.  
 
 
  1. function func1(){   
  2.     var start = new Date().getTime();   
  3.     for(var i = 0; i < 10000; i++){   
  4.         var but1 = document.getElementById("but1");   
  5.         var but2 = document.getElementById("but2");   
  6.         var inputs = document.getElementsByTagName("input");   
  7.         var divs = document.getElementsByTagName("div");   
  8.         var but1 = document.getElementById("but1");   
  9.         var but2 = document.getElementById("but2");   
  10.         var inputs = document.getElementsByTagName("input");   
  11.         var divs = document.getElementsByTagName("div");   
  12.         var but1 = document.getElementById("but1");   
  13.         var but2 = document.getElementById("but2");   
  14.         var inputs = document.getElementsByTagName("input");   
  15.         var divs = document.getElementsByTagName("div");   
  16.         var but1 = document.getElementById("but1");   
  17.         var but2 = document.getElementById("but2");   
  18.         var inputs = document.getElementsByTagName("input");   
  19.         var divs = document.getElementsByTagName("div");   
  20.         var but1 = document.getElementById("but1");   
  21.         var but2 = document.getElementById("but2");   
  22.         var inputs = document.getElementsByTagName("input");   
  23.         var divs = document.getElementsByTagName("div");   
  24.         var but1 = document.getElementById("but1");   
  25.         var but2 = document.getElementById("but2");   
  26.         var inputs = document.getElementsByTagName("input");   
  27.         var divs = document.getElementsByTagName("div");   
  28.     }   
  29.     var end = new Date().getTime();   
  30.     alert("用时 " + (end - start) + " 毫秒");   
  31. }   
  32. function func2(){   
  33.     var start = new Date().getTime();   
  34.     var doc = document;   
  35.     for(var i = 0; i < 10000; i++){   
  36.         var but1 = doc.getElementById("but1");   
  37.         var but2 = doc.getElementById("but2");   
  38.         var inputs = doc.getElementsByTagName("input");   
  39.         var divs = doc.getElementsByTagName("div");   
  40.         var but1 = doc.getElementById("but1");   
  41.         var but2 = doc.getElementById("but2");   
  42.         var inputs = doc.getElementsByTagName("input");   
  43.         var divs = doc.getElementsByTagName("div");   
  44.         var but1 = doc.getElementById("but1");   
  45.         var but2 = doc.getElementById("but2");   
  46.         var inputs = doc.getElementsByTagName("input");   
  47.         var divs = doc.getElementsByTagName("div");   
  48.         var but1 = doc.getElementById("but1");   
  49.         var but2 = doc.getElementById("but2");   
  50.         var inputs = doc.getElementsByTagName("input");   
  51.         var divs = doc.getElementsByTagName("div");   
  52.         var but1 = doc.getElementById("but1");   
  53.         var but2 = doc.getElementById("but2");   
  54.         var inputs = doc.getElementsByTagName("input");   
  55.         var divs = doc.getElementsByTagName("div");   
  56.         var but1 = doc.getElementById("but1");   
  57.         var but2 = doc.getElementById("but2");   
  58.         var inputs = doc.getElementsByTagName("input");   
  59.         var divs = doc.getElementsByTagName("div");   
  60.     }   
  61.     var end = new Date().getTime();   
  62.     alert("用时 " + (end - start) + " 毫秒");   

上面代码中,第二种情况是先把全局对象的变量放到函数里面先保存下来,然后直接访问这个变量,而第一种情况是每次都遍历作用域链,直到全局环境,我们看到第二种情况实际上只遍历了一次,而第一种情况却是每次都遍历了

5、避免双重解释

双重解释的情况也是我们经常会碰到的,有的时候我们没怎么考虑到这种情况会影响到效率,双重解释一般在我们使用eval、new Function和setTimeout等情况下会遇到,我们看看下面的例子:

 
 
  1. <div id="demo"></div>   
  2. <input id="but1" type="button" οnclick="func1()" value="效率低"/>   
  3. <input id="but2" type="button" οnclick="func2()" value="效率高"/>   
 
 
  1. var sum, num1 = 1, num2 = 2;   
  2. function func1(){   
  3.     var start = new Date().getTime();   
  4.     for(var i = 0; i < 10000; i++){   
  5.         var func = new Function("sum+=num1;num1+=num2;num2++;");   
  6.         func();   
  7.     }   
  8.     var end = new Date().getTime();   
  9.     alert("用时 " + (end - start) + " 毫秒");   
  10. }   
  11.     
  12. function func2(){   
  13.     var start = new Date().getTime();   
  14.     for(var i = 0; i < 10000; i++){   
  15.         sum+=num1;   
  16.         num1+=num2;   
  17.         num2++;   
  18.     }   
  19.     var end = new Date().getTime();   
  20.     alert("用时 " + (end - start) + " 毫秒");   

在IE6.0下还是有影响,而且在Firefox下,使用eval对效率的影响程度更加厉害,在Firefox下,如果10000次循环,需要十多秒的时间,所以我把循环都变成了1000次。看代码和报告。

 
 
  1. var sum, num1 = 1, num2 = 2;   
  2. function func1(){   
  3.     var start = new Date().getTime();   
  4.     for(var i = 0; i < 1000; i++){   
  5.         eval("sum+=num1;num1+=num2;num2++;");   
  6.     }   
  7.     var end = new Date().getTime();   
  8.     alert("用时 " + (end - start) + " 毫秒");   
  9. }   
  10. function func2(){   
  11.     var start = new Date().getTime();   
  12.     for(var i = 0; i < 1000; i++){   
  13.         sum+=num1;   
  14.         num1+=num2;   
  15.         num2++;   
  16.     }   
  17.     var end = new Date().getTime();   
  18.     alert("用时 " + (end - start) + " 毫秒");   

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值