也谈JavaScript代码性能优化

差不多两年前写了个选择器whiz,除在DOM查找方面做了许多优化工作之外,还在代码优化上做了很多工作,一直没有分享。抽空总结一下,基本上在jQuery、Mootools和YUI的源码里面都可以看到这些写法。有些是已经在网上分享很多遍了,众所周知的,也有一些可能写了多年的JavaScript的开发人员也不一定想得到的。如果有说得不正确的地方,还请大家指出。还有特别说明的是,其中某些写法不是很推荐,虽然代码简洁了,但是有可能造成阅读困难。

1.尽量使用源生方法(Native Method)

js是解释性语言,相比编译性语言执行速度要慢。如果浏览器已经实现了该方法,就不要再用js再去实现一遍了。另外,绝大部分情况下,浏览器已经实现的方法已经在算法方面做了很多优化,再重复实现一遍只是浪费时间和精力还有带宽。当然,如果你只是为了练习算法,那另当别论。

2.尽可能减少循环次数

代码的瓶颈大多在循环,少一层循环,就能数倍地提高性能。如果要对一个数组的每个元素进行多次操作,尽可能使用一次循环,多次操作,而不是多次循环,每次循环执行一次操作。尤其是在进行多个正则匹配的时候,尽可能合并正则表达式,在一次遍历中尽可能找到相应的匹配。

3.循环的另外一种写法

通常循环的写法:

var objs = [obj1, obj2, obj3], i = 0; len = objs.length;
for(i = 0; i < len; i++){
    dosth(obj);
}

当循环遍历的对象是object时,可以采用下面的方式来写:

var objs = [obj1, obj2, obj3], obj, i = 0;
while(obj = objs[i++]){
    dosth(obj);
}

特别注意,如果你的数组里面有可能出现0, false, null等等在条件判断为false的值,这种写法是不正确的。

4.某些情况下switch的另外一种写法

通常的switch写法:

function fun_a(){}
function fun_b(){}
function fun_c(){}
switch(con){
    case 'a':
        fun_a();
        break;
    case 'b':
        fun_b();
        break;
    case 'c':
        fun_c();
        break;
}

另外一种写法:

function fun_a(){}
function fun_b(){}
function fun_c(){}
var funs = {
        'a': fun_a,
        'b': fun_b,
        'c': fun_c
    };
funs[con]();

取值或者函数调用都可以用类似的方式来做。

5.条件判断的另外一种写法

通常情况下:

if(a){
  dosth();
}

可以这样写:

a && dosth();

6.创建对象的另外一个办法,不使用new

很多时候,我们要连续创建一些简单的object对象,并且拥有默认的属性,很多人会这么写:

function Klass(){
    this.prop_a = '';
    this.prop_b = [];
    this.prop_c = 0;
}
var objs = [], i = 0, obj;
while(i<100){
    obj = new Klass();
    obj.prop_c = i;
    objs.push(obj);
}

换种写法看看:

function create(){
    return {
        prop_a : '',
        prop_b : [],
        prop_c : 0
    };
}
var objs = [], i = 0, obj;
while(i<100){
    obj = create();
    obj.prop_c = i;
    objs.push(obj);
}

当然还有直接声明的方式,但是复用性会差一些。

7.用来做标记的变量尽可能使用布尔类型

直接用true和false做标记,不要使用数字或者字符串的1和0来做标记,直接也高效。

其他的优化方法已经有很多分享了,大家可以Google一下,另外《javascript高级程序设计》一书中也对JavaScript性能优化做了较为详细的阐述。

2 comments on “也谈JavaScript代码性能优化”

发表评论

电子邮件地址不会被公开。 必填项已用*标注