JS 性能提升

来源:互联网 发布:淘宝商城女装夏装 编辑:程序博客网 时间:2024/06/07 00:53

作用域

避免全局查找
全局变量和函数的由于需要沿着作用域链进行查找,开销大于局部变量;因此,涉及到多次访问同一个全局变量时,可以先将其保存在一个局部变量中用于后续调用,这样可以降低一些开销;

避免使用with语句
由于调用with语句会临时创建一个单独的作用域,延长了作用域链,因此增加了作用域链查找开销,应当尽量避免;


选择正确的方法

避免不必要的属性查找

原因前边已经说了,这是一个复杂度为O(n)的操作;

循环优化

在《高性能JavaScript》中也提到过,循环中的循环体是一个很耗性能的部分,有效优化这部分可以大幅提升性能,关于循环体的优化可以使用Duff设备将其展开,在处理大数据量时性能明显提升,具体方法可以参考《达夫设备 JavaScript》;

另外,简化循环终止条件、减值迭代、后测试循环(do-while)也可以带来一定的性能提升;

避免双重解释

也就是避免类似于eval()、setTimeout()或者构造函数被传入了一个字符串参数;示例中的情况均应当避免;因为解析这类代码需要实例化一个新的解析器解析内部代码,因此开销比较大;

eval("alert('hello world')");setTimeout("alert('hello world')", 100);new Function("alert('hello world')");

注意事项

1、允许的情况下尽量使用原生方法;原生的方法是基于C/C++等编译型语言实现的,因此速度比JavaScript解析快很多;
2、位运算符:位运算符的速度比其他算术运算或布尔运算快,在进行逻辑运算、奇偶性判断、数值交换、取模等操作时使用位运算符可以有效提升性能;

var a = 10, b = 1;a = a ^ b;b = a ^ b;a = a ^ b;console.log(a);  // 1console.log(b);  // 10

3、在需要大量条件判断时使用switch比使用if-else更高效;


最小化语句数

变量声明

需要声明多个变量时,可以使用一条声明语句声明所有变量,比分别声明快;

自增自减变量

没什么说的,尽量合并到其他语句中;

声明数据和对象时尽可能使用字面量形式


优化DOM交互

最小化现场更新

《高性能JavaScript》中也提到过,当要操作的DOM节点位于DOM渲染树中时,更新它们会导致浏览器重排和重绘,有很大的性能损耗;应当尽可能减少DOM更新操作;

可以使用DocumentFragment文档片段实现。它不属于DOM树,向它上边添加DOM节点不会引起浏览器的reflow和repaint;可以先把所有待更新节点添加到DocumentFragment中,然后使用appendChild()方法将所有待更新节点一次性添加,有效地降低了重排重绘的次数;在使用appendChild()方法时只会讲DocumentFragment的子节点树添加到DOM树中;

创建DocumentFragment对象时使用document.createDocumentFragment()方法,同时可以把它保存到局部变量中减少属性查找次数;


重点内容

根据《JavaScript高级程序设计》所言,使用innerHTML进行大量DOM节点修改时比createElement() + appendChild()等DOM方法快得多;原因是设置innerHTML值时,会在后天创建一个HTML解析器并使用内部的编译好的DOM调用创建DOM结构,而普通的DOM方法是使用JavaScript的解释执行DOM调用;


事件代理/ 事件委托

处理列表等相似的DOM结构时,可以把事件处理程序绑定到较高层的DOM节点进行统一处理,不必为每个节点都单独绑定一个事件,可以节省内存开销,同时减少了DOM交互;


HTMLCollection

HTMLCollection是一个会实时更新的对象,访问它的属性或方法的开销都很大,不需要使用其实时信息的情况下最好将其保存到局部变量再调用,以减小查询次数;尤其在循环体中尽量避免多次调用该对象;

以下条件下会返回HTMLCollection对象:
1、调用了getElementByTagName();
2、获取元素的childNodes属性;
3、获取元素的attributes属性;
4、访问document.forms、document.images等特殊集合;


参考文献
1、https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment
2、《高性能JavaScript》
3、《JavaScript高级程序设计》