转:大型应用下的 AngularJS 性能

前端之家收集整理的这篇文章主要介绍了转:大型应用下的 AngularJS 性能前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

原文地址:http://web.jobbole.com/82060/


大型应用下的 AngularJS 性能

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 循环

避免在一个循环中调用外部函数。一旦任何调用可以在循环外部的完成,它将大大加速你的系统。例如:

上面将大大慢于下面:

http://jsperf.com/for-loop-perf-demo-basic

4.2 Dom访问

需要着重注意的是访问DOM是昂贵的。

2
unbinder . $ watch 'scopeValueToBeWatcher' newVal oldVal { ;
unbinder //this line removes the watch from $$watchers.

如果你不能过早地解除绑定,记得在$on(‘$destroy’)解除绑定

9.4$on,$broadcast,and$emit

像$watch,这些都是慢的,因为事件(可能)遍历你的整个scope的层次结构。除此之外,它们会像GOTO一样,让您的应用程序很难调试。幸运的是,像$watch,如果有必要他们可以通过返回函数解除绑定(记得在$on('$destroy')解除绑定,同时可以通过正确地使用服务和scope继承来完全避免)。

9.5$destroy

如前所述,你应该总是显式调用$on(‘$destroy’),解绑你所有的watchers和事件监听器,并取消任何$timeout实例,或其他正在进行的异步交互。这不仅是确保安全良好的实践,同时标记你的scope让垃圾收集更迅速。不这样做会让他们在后台运行,浪费cpu和RAM。

尤其重要的是要记住的在$destroy调用中解绑任何在指令元素上定义的DOM事件监听器。不这样做,将会导致在旧浏览器发生内存泄漏和在现代浏览器发生垃圾收集缓慢。一个非常重要的结论是,你需要记住在你移除DOM前调用scope.$destroy。

9.6$evalAsync

scope.$evalAsync是一个强大的工具,它让你把要执行的操作在当前digest周期的末尾进行排队,不会导致在scope修改后的另一个digest周期。这需要基于具体案例思考,但预期的效果,evalAsync可以大大提高页面性能

10 指令问题

10.1 隔离的Scope和Transclusion

隔离Scope和Transclusion是Angular最令人兴奋的一些事情。他们允许构建可重用、封装的组件,它们在语法上和概念上优雅,让Angular出彩的一个核心部分。

然而,他们有一个权衡。默认情况下,指令不创建一个scope,而是拥有和他们的父元素相同的范围。通过创建一个新的隔离scope或Transclusion,来创建一个新的对象去跟踪和添加新的watch,因此会减慢我们的应用程序。总是在你使用它前停下来并思考有没有必要。

10.2 编译周期

指令编译功能在附加scope之前运行,这是运行任何DOM操作(例如绑定事件)的最佳的地方。从性能的角度来看,需要重要认识的,是元素和属性传递到编译函数使用了原始html模板,它在任何Angular变化前。在实践中这意味着,DOM操作完成,将运行一次,直接使用。另一个重要的点事prelink和postlink的区别。简而言之,prelinks运行由外而内,而postlinks运行由内而外。因此,prelinks提供轻微的性能提升,因为他们阻止内部指令运行第二次digest周期,当父节点在prelink修改scope。然而,子DOM可能不可用。

11 DOM事件问题

Angular提供了许多预先编译好的DOM事件指令. ng-click,ng-mouseenter,ng-mouseleave等等。每次这些事件触发时都会调用scope.$apply()。一个更有效的方法是直接使用addEventListener绑定,然后必要时使用scope.$digest。

12 总结

12.1 AngularJS:不好的部分

  • ng-click和其他DOM事件
  • scope.$watch
  • scope.$on
  • 指令postLink
  • ng-repeat
  • ng-show and ng-hide

12.2AngularJS:好的(性能)部分

  • track by
  • 使用::只绑定一次
  • compile和preLink
  • $evalAsync
  • 服务,作用域继承,通过引用传递对象
  • $destroy
  • 解绑watches和事件监听器
  • ng-if和ng-switch

了解更多,https://www.airpair.com/angularjs/posts/angularjs-performance-large-applications#WLXbzSUvg6aWzlUP.99

原文链接:https://www.f2er.com/angularjs/149208.html

猜你在找的Angularjs相关文章