编写高性能Javascript代码的若干建议

jopen 8年前

多年来,Javascript一直在web应用开发中占据重要的地位,但是很多开发者往往忽视一些性能方面的知识,特别是随着计算机硬件的不断升级,开发者越发觉得Javascript性能优化的好不好对网页的执行效率影响不明显。但在某些情况下,不优化的Javascript代码必然会影响用户的体验。因此,即使在当前硬件性能已经大大提升的时代,在编写Javascript代码时,若能遵循Javascript规范和注意一些性能方面的知识,对于提升代码的可维护性和优化性能将大有好处。

下面给出编写高性能的Javascript代码的若干建议:

1、尽量不要用for-in 循环去访问数组,建议用 for 循环进行循环:

JavaScript

function foo1() {          var i, b, c=[1,2,3];          for (i in c) {              b = c[i];              if(b === "2")                  return b;          }      }       //性能更好      function foo2() {          var i, b, c=[1,2,3];          for (i=0;i<c.length;i++) {              b = c[i];              if(b === "2")                  return b;          }  }
functionfoo1(){    vari,b,c=[1,2,3];    for(iinc){     b=c[i];     if(b==="2")      returnb;    }   }    //性能更好   functionfoo2(){    vari,b,c=[1,2,3];    for(i=0;i<c.length;i++){     b=c[i];     if(b==="2")      returnb;    }  }

2、建议将对象进行缓存处理,特别是DOM访问是比较消耗资源的:

JavaScript

//c.length没有缓存,每次迭代都要计算一下数组的长度      function foo1() {          var i, b, c=[1,2,3];          for (i=0;i&lt;c.length;i++) {              b = c[i];              if(b === "2")                  return b;          }      }       //性能更好,第一次将数组的长度缓存到变量l中,第二次及后续的循环无需计算数组长度      function foo2() {          var i, b, c=[1,2,3],l;          for (i=0,l=c.length;i&lt;l;i++) {              b = c[i];              if(b === "2")                  return b;          }      }
//c.length没有缓存,每次迭代都要计算一下数组的长度  functionfoo1(){   vari,b,c=[1,2,3];   for(i=0;i<c.length;i++){    b=c[i];    if(b==="2")     returnb;   }  }   //性能更好,第一次将数组的长度缓存到变量l中,第二次及后续的循环无需计算数组长度  functionfoo2(){   vari,b,c=[1,2,3],l;   for(i=0,l=c.length;i<l;i++){    b=c[i];    if(b==="2")     returnb;   }  }

JavaScript

//document.getElementById('info')没有缓存,每次都要遍历DOM      function foo1() {          var e;          document.getElementById('info').innerHTML="call 1";          document.getElementById('info').innerHTML="call 2";        }       //性能更好,第二次无需访问DOM      function foo2() {         var e=document.getElementById('info');         e.innerHTML="call 1";             e.innerHTML="call 2";      }
//document.getElementById('info')没有缓存,每次都要遍历DOM  functionfoo1(){   vare;   document.getElementById('info').innerHTML="call 1";   document.getElementById('info').innerHTML="call 2";  }   //性能更好,第二次无需访问DOM  functionfoo2(){     vare=document.getElementById('info');     e.innerHTML="call 1";      e.innerHTML="call 2";  }

3、建议不要在函数内进行过深的嵌套判断:

JavaScript

//函数内嵌套判断语句过多       function foo1() {              var r={};              r.data={};              r.data.myProp=2;              if (r) {              if (r.data) {                  if (r.data.myProp) {                      //逻辑处理                  }                   else {                      //逻辑处理                  }              }      }        }       //性能更好      function foo2() {           var r={};            r.data={};            r.data.myProp=2;          if (!r) return;          if (!r.data) return;                  if (r.data.myProp) {              //逻辑处理          } else {               //逻辑处理          }      }
//函数内嵌套判断语句过多   functionfoo1(){    varr={};    r.data={};    r.data.myProp=2;    if(r){    if(r.data){     if(r.data.myProp){      //逻辑处理     }     else{      //逻辑处理     }    }  }  }   //性能更好  functionfoo2(){    varr={};     r.data={};     r.data.myProp=2;   if(!r)return;   if(!r.data)return;     if(r.data.myProp){    //逻辑处理   }else{     //逻辑处理   }  }

4、避免循环引用,防止内存泄漏:

JavaScript

//需要jQuery  function foo1(e,d) {      $(e).on("click", function() {             //对d进行逻辑处理               cbk(d);                      }         });  }    //打破循环!  function foo2(e, d) {      $(e).on("click", cbk(d));  }  function cbk (d) {   //逻辑处理  }
//需要jQuery  functionfoo1(e,d){      $(e).on("click",function(){       //对d进行逻辑处理         cbk(d);          }        });  }  //打破循环!  functionfoo2(e,d){      $(e).on("click",cbk(d));  }  functioncbk(d){  //逻辑处理  }

5、建议避免在函数内返回一个未声明的变量,会污染外部变量:

JavaScript

function foo(a, b) {      r = a + b;      return r; //r未声明,则创建了一个全局变量  }
functionfoo(a,b){      r=a+b;      returnr;//r未声明,则创建了一个全局变量  }

6、var声明变量,建议写在多行

JavaScript

//自己测试结果是foo1快,但也有一种观点是foo2快  function foo1() {      var c = 1;      var sum=0;      var d = 0;      var e;  }    function foo2() {      var c = 1,sum=0, d = 0, e;  }
//自己测试结果是foo1快,但也有一种观点是foo2快  functionfoo1(){   varc=1;   varsum=0;   vard=0;   vare;  }  functionfoo2(){   varc=1,sum=0,d=0,e;  }

说明:其实单个函数时间上差别较小,这里采用循环多次用累计时间进行性能对比,不同PC配置或者浏览器测试结果可能存在差异。

原文出处: JackWang-CUMT