AngularJS性能优化
几个概念
域$scope和更新周期DigestCycle
AngularJS的域本质上是一些JavaScript对象,它们从一些预定义的对象继承而来。基本上,小的域比大的域运行要快。
每创建一个新的域,都会给垃圾回收器添加更多待回收的内容。
每一个域都会存放一个由方法组成的数组$$watchers.
每当域中的一个值(属性)或绑定的DOM,如ng-repeat,ng-switch和ng-if等等,调用$watch时,一个函数(function)就会添加到相对应域中的$$watchers数组队列中。
当域中的值发生改变时,在$$watchers中所有的watchers函数都会被触发调用。并且当它们中的任何一个修改了域中的某个值时,它们会被再次触发执行。这个过程会一直循环下去直到$$watcher数组队列中不再做任何更改或抛出异常为止。
另外,如果任何代码执行$scope.$apply(),都会触发更新周期。
在设计AngularJS时应该遵守的一般准则
大型对象和服务器调用
我们要尽可能地简化我们的对象。当对象从服务器返回时,这一点尤为重要。
监视函数(watching functions)
不要将任何东西(ng-show、ng-repeat等等)直接绑定到一个函数。不要直接监视任何函数的返回值。该函数会在每个更新周期都执行,可能会降低你应用的速度。
监视对象 (watching objects)
虽然AngularJS提供了第三个可选参数来监视整个对象的改动--将调用$watch的第三个参数设为true。这是非常不好的想法,一个更好的解决办法是依靠服务和对象引用,监视域之间的变化。
需要注意的代码技巧
避免在循环内部调用函数
变量作用范围限制的越紧密越好,这样垃圾回收器可以更快回收空间。
可能的话,避免使用ng-repeat指令
合理利用一次性绑定机制
AngularJS最近的几次更新中引入了一个很有用的功能:一次性的渲染模板某些变量,并且它们不会受到未来Model变化的影响。这对于改善性能特别有用,一般情况,设置模板数据:
<i>{{tip}}</i>
使用一次性变量渲染语法则可以这样:
<i>{{ :: tip }}</i>
这样当AngularJS按常规处理完DOM和该变量后,他会在内部$$watchers的监控列表中删除这些一次性变量。
适当的直接操作DOM