1 介绍
无论你是为一个拥有大量用户的旧应用编写一个Angalar前端,或已有的Angular应用正在迅速扩张,性能都是一个重要方面。理解什么会导致AngularJS应用程序响应变慢,并且知道在开发过程中对此做出一些权衡是非常重要的。本文将讲述一些AngularJS可能导致的常见性能问题,以及给出在未来如何修复和避免他们的建议。
1.1 需求,假设
本文假设对JavaScript编程语言和AngularJS比较熟悉。当使用特定于版本的特性,他们会被标注。如果你已经花了一些时间在玩Angular,但还没有认真地处理性能问题,那么你最能吸收这篇文章的要义。
2 行业工具
2.1 基准分析
最出色的代码基准测试工具就是 jsPerf。为了增强可读性,我将在后面相关的部分链接到特定的test runs(测试例子)。
2.2 性能分析
Chrome开发工具有一个很棒的Javascript分析器。我强烈推荐阅读本系列文章。
2.3 Angular Batarang
由Angular 核心团队维护的一个专用的Angular 调试器, 在GitHub上可以获取。
3 软件性能
有两个导致软件性能差的根本原因。
第一个是算法的时间复杂度。解决这个问题很大程度上超出了本文的范围,一般可以这样说,时间复杂度是衡量一个程序需要做多少次的比较来实现一个结果。比较数量越多,程序越慢。一个简单的例子是线性查找与二分查找。线性查找对于同一组数据需要进行更多的比较,因此会慢。时间复杂度的详细讨论,请参考 维基百科文章。
第二个原因是空间复杂度。这是一台电脑运行你的解决方案需要多少“空间”或内存的测量。需要的内存越多,解决方案就越慢。本文将讨论的大多数问题,围绕空间复杂度。详细讨论,请参阅这里.。
4 Javascript性能
有些要说的是关于Javascript性能,这里并不局限于Angular。
4.1 循环
避免在一个循环中调用外部函数。一旦任何调用可以在循环外部的完成,它将大大加速你的系统。例如:
1 2 3 4 5 |
var sum = 0; for(var x = 0; x < 100; x++){ var keys = Object.keys(obj); sum = sum + keys[x]; } |
上面将大大慢于下面:
1 2 3 4 5 |
var sum = 0; var keys = Object.keys(obj); for(var x = 0; x < 100; x++){ sum = sum + keys[x]; } |
http://jsperf.com/for-loop-perf-demo-basic
4.2 Dom访问
需要着重注意的是访问DOM是昂贵的。
1 |
angular.element('div.elementClass') |
虽然这在AngularJS应该不是一个问题,意识到这一点仍然是有用的。这里说的第二件事是,DOM树应该保持尽可能小。
最后,如果可能的话,避免修改DOM,不设置内联样式。这是由于JavaScript重排。重排的深度的讨论超出了本文的范围,但是这里可以找到一个不错的参考。
4.3 变量作用域和垃圾收集
所有变量作用域尽可能紧密,会让JavaScript垃圾收集器尽早地释放你的内存。这是通常JavaScript,特别是Angular缓慢,延迟,不响应的一个极其常见原因。请注意以下问题:
1 2 3 4 5 |
function demo(){ var b = {childFunction: function(){console.log('hi this is the child function')}; b.childFunction(); return b; } |
函数终止时,将没有必要进一步引用b,垃圾收集器将释放内存。然而,如果在其他地方有这样一行代码:
1 |
var cFunc = demo(); |
我们现在将对象绑定到一个变量同时保持引用,阻止垃圾收集器回收它。虽然这可能是必要的,重要的是你要知道对象引用有什么影响。
4.4 数组和对象
有许多事情要谈。首先且最简单的是,数组总是比对象更快,数字访问好于非数字访问。
1 2 3 |
for (var x=0; x<arr.length; x++) { i = arr[x].index; } |
上面快于下面
1 2 3 |
(var x=0; x<100; x++) { i = obj[x].index; } |
还快于
tarea wrap="soft" class="crayon-plain print-no" data-settings="dblclick" readonly style="-moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4; font-size: 13px !important; line-height: 15px !important;">
var keys = Object.keys(obj);
for (var x = 0; x < keys.length; x++){
i = obj[keys[x]].index;
}
|