众所周知,js是一种解释型语言,执行速度要比编译型语言慢得多。为提高性能,我们可以通过以下方法改进代码的整体性能
1、减少作用域链上的访问
在js中访问全局变量总比访问局部变量要慢,因为要遍历作用域链。
1.1、避免全局查找。
将全局变量赋值给局部变量。例如下面这个例子
function updateUI() {
var imgs = document.getElementByTagName("img");
for(var i = 0, len = imgs.length; i < len; i++) {
imgs[i].title = document.title + " image " + i;
}
}
注意,updateUI中包含了二个对于全局变量document对象的引用,特别是循环中的document引用,查到次数是O(n),
每次都要进行作用域链查找。通过创建一个指向document的局部变量,就可以通过限制一次全局查找来改进这个函数的性能。
function updateUI() {
var doc = document;
var imgs = doc.getElementByTagName("img");
for(var i = 0, len = imgs.length; i < len; i++) {
imgs[i].title = doc.title + " image " + i;
}
}
1.2、避免使用with语句。
with语句会创建自己的作用域,会增长作用域链的长度
2、保存对象属性。
在js中访问对象总是比访问变量要慢的多,因此当需要多次用到对象属性的时候,应将其存储在局部变量中。
3、循环优化
3.1、减值迭代
大多数循环都是变量从0开始增加到最大值,在很多情况下,从最大值开始,逐步减值到最小值的迭代器更有效
3.2、简化终止条件
未作优化:
for(var index = 0;index < array.length;index++){}
优化后:
for(var index = 0,len = array.length;index < len;index++){}
3.3、使用后测试循环
常用for和while循环都是前测试循环,而do-while可以避免最初计算终止条件的计算,因此效率高些。
var i values.length - 1;
if(i > -1) {
do {
......;
}while(--i >= 0);
}
3.4、消除循环
当循环次数可以确定,可以采用函数迭代。
4、避免使用eval
使用eval时,需要新启动一个解析器来解析新的代码,实例化一个解析器是一笔不小的开销。
5、尽可能使用原生方法
比如switch和位操作
6、最小语句数
6.1、多个变量声明
避免:var a = 1;
var b = 2;
var c = 3;
正确:var a = 1,b = 2,c = 3;
6.2、插入迭代值
避免:
var name = values[i];
i++;
提倡:
var name = values[i++];
6.3、使用数组和对象字面量时避免使用构造函数形式
7、优化DOM操作
7.1.最小化现场更新
一旦你需要访问的DOM部分是已经显示的页面的一部分,那么你就是在进行一个现场更新。之所以叫现场更新,
是因为需要立即(现场)对页面对用户的显示进行更新,每一个更改,不管是插入单个字符还是移除整个片段,都有 一
个性能惩罚,因为浏览器需要重新计算无数尺寸以进行更新。现场更新进行的越多,代码完成执行所花的时间也越长。
7.2.多使用innerHTML
有两种在页面上创建DOM节点的方法:使用诸如createElement()和appendChild()之类的DOM方法,以及使用
innerHTML。对于小的DOM更改,两者效率差不多,但对于大的DOM更改,innerHTML要比标准的DOM方法创建同样的DOM结
构快得多。当使用innerHTML设置为某个值时,后台会创建一个HTML解释器,然后使用内部的DOM调用来创建DOM结构,
而非基于JS的DOM调用。由于内部方法是编译好的而非解释执行,故执行的更快。