相信写代码对于大部分人都不难,但想写出高性能的代码就需要一定的技术积累啦,下面是一些优化JavaScript代码性能的常见方法。

一.注意作用域

   1.避免全局查找

        使用全局变量和函数肯定要比局部的开销更大,因为要涉及作用域链上的查找,请看以下函数: 

1  function demo1() {
2     var imgs = document.getElementByTagName("img");  //获取页面所有img标签
3 
4      for(var i = 0; i <= imgs.length; i++) {
5         imgs[i].title = document.title + "image" + i;   
6      }
7  }

       上面的代码每执行一次for循环都会在全局寻找document,一旦循环次数很多,那么就严重影响了性能,我们可以在for循环开始之前就把document的引用保存在一个局部变量。改进代码如下:

1 function demo1() {
2     var imgs = document.getElementByTagName("img");  //获取页面所有img标签
3     var doc = document;   //局部引用全局变量document
4 
5      for(var i = 0; i <= imgs.length; i++) {
6         imgs[i].title = doc.title + "image" + i;   
7     }
8  }

 

二.选择正确方法

   1.优化循环

1 for(var i = 0; i <=imgs.length; i++) {
2    //执行代码
3 }

    上面代码每次执行循环都会重新计算imgs的长度,一旦循环次数很多,那么积少成多就会影响到代码性能,我们只需在for循环执行之前把imgs的长度保存在一个变量中即可,这样就不用每次都是计算imgs的长度,改进代码如下:

1  var length = imgs.length;    //把imgs的长度保存在一个变量中
2  for(var i = 0; i <=length; i++) {
3     //执行代码
4  }

   

   2.尽量使用原生方法

     只要有可能,使用原生方法而不是自己用javascript重写一个。原生方法是用诸如c/c++之类的编译型语言写出来的,所以要比JavaScript的快很多很多。

   3.使用switch替代if-else

      如果有一系列复杂的if-else语句,可以转化成单个switch语句则可以得到更快的代码。还可以通过case语句按照最可能的到最不可能的顺序进行组织,来进行进一步优化switch语句。

 

三.最小化语句数  

    1.多个变量申明,javaScript代码中的语句数量也影响所执行的操作的速度,完成多个操作的单个语句要比完成单个操作的多个语句快。

1  //四个语句申明变量,浪费!
2  var name = "Bill";
3  var  age = 10;
4  var  sex = "man";
5 
6  //一个语句申明变量,干的漂亮!
7  var name = "Bill",
8      age = 10,
9      sex = "man";

 

   2.插入迭代值,当使用迭代值(也就是在不同的位置进行增加或减少的值)的时候,尽可能合并语句。

//两个语句,浪费!
 var age = values[i];
 i++;

 //一个语句,干的漂亮!
 var age = values[i++];

   3.使用数组和对象字面量,你可能看过两种创建数组和对象的方法:使用构造函数或是使用字面量,使用构造函数总是要用到很多语句来插入元素或定义属性,而字面量可以将这些操作在一个语句中完成。

1  //4个语句创建和初始化数组,浪费!
 2  var values = new Array();
 3  values[0] = 123;
 4  values[1] = 456;
 5  values[2] = 789;
 6 
 7  //4个语句创建和初始化对象,浪费!
 8  var person = new Object();
 9  person.name = "Bill";
10  person.age = 10;
11  person.sayName = function () {
12   console.log(this.name);
13  }
14 
15  //1个语句创建和初始化数组,干得漂亮!
16  var values = [123, 456, 789];
17  
18  //一个语句创建和初始化对象,干的漂亮!
19  var person = {
20        name : "bill",
21        age : 10,
22        sayName : function () {
23             console.log(this.name)
24        }
25  };
26

 

四.优化DOM交互

   1.使用文档碎片减少DOM交互次数,DOM交互越多,性能越慢。

1  var list = document.getElementById("myList"),
2        item,
3        i;
4 
5  for (i = 0; i <= 10; i++) {
6       item.document.createElement("li");
7       list.appendChild(item);
8       item.appendChild(document.createTextNode(" Item" + i));
9  }

   上面代码每执行一次for循环都会向DOM插入新的元素,一旦for循环次数很多,那么将严重影响代码性能,所以解决办法就是减少DOM交互,于是我们使用createDocumentFragment方法创建虚拟节点,把要插入DOM的元素先插入该虚拟节点,循环完之后再把虚拟节点插入DOM,虚拟节点是不会渲染出来的,只会渲染它的子节点。改进代码如下:

1  var list = document.getElementById("myList");
 2        fragment = document.createDocumentFragment(),
 3        i;
 4 
 5  for (i = 0; i < 10; i++) {
 6       item = document.createElement("li");
 7       fragment.appendChild(item);
 8       item.appendChild(document.createTextNode("Item" + i));
 9  }
10  
11  list.appendChild(fragment);

  2.使用innerHTML。有两种在页面上创建DOM节点的方法:诸如createElement()和appendChild()之类的DOM方法,以及使用innerHTML。当把innerHTML设置为某个值时,后台会创建一个HTML解析器,然后使用内部的DOM调用来创建DOM结构,而非基于JavaScript的DOM调用,由于内部方式是编译好的而非解释执行的,所以执行快的多。

   3.使用事件委托,把事件绑定在祖先节点,由于有事件冒泡,当事件触发时根据event对象的target属性可以知道具体事件是在那个子元素发生的。从而执行不同的行为。这样就不必每个子节点都绑定事件。