我们正在为我们正在为银行建立的Angular应用程序冲击性能问题。
不幸的是,显示代码片段是违反合同的行为。无论如何,我可以描述一些正在发生的主要问题,我希望可以推荐最佳实践。
应用程序结构:
如果你看一下时间表。我们花了很多时间在jQuery解析html方法,jQuery重新计算stye方法,GC事件(垃圾收集)。我想最小化这些应该可以加快速度。它们都是Angular生命周期的一部分,但可能有更好的方法来避免它们。以下是探查器的一些截图:
最终,随着重复表格的数量超过5,应用程序缓慢。每个表单与其他表单相对无关。我们试图不在表格之间观看任何共享属性。
答案 0 :(得分:21)
您需要创建自定义指令,以便使用angular来抑制性能问题。与ember angular不同的是,所有铃声和口哨都打开了,你可以自己调低音量。以下是我为帮助您而制定的一些指令。并非您的应用中的所有数据都需要双向数据绑定,因此您可以通过在需要的页面中放弃监视表达式来节省宝贵的CPU功率。所有这些指令都会将数据绑定一次而不管它。
https://gist.github.com/btm1/6802599
https://gist.github.com/btm1/6802312
https://gist.github.com/btm1/6746150
上面的答案之一谈到ng-repeat有巨大的性能命中,所以我给你“set-repeat”一次性数据绑定重复指令:)
答案 1 :(得分:8)
如果没有关于您的问题的更多信息,很难提供解决方案,但我最近经历过(和解决)a performance issue可能与您看到的类似,并且与$ digest循环无关。
您将发现的大多数有关angularjs性能的讨论(包括excellent post from Misko)都与脏检查和$ digest循环的性能有关。但这不是您可以使用angularjs遇到的唯一性能问题。第一步应该是确定摘要周期是否是您的问题。为此,您可以使用batarang,或只是查看您的应用程序,并确切地说它是缓慢的。当摘要周期很慢时,基本上与UI的任何交互都会很慢。
OTOH,你可以拥有一个具有快速摘要周期的应用程序,只有在加载,切换视图或以其他方式更改要显示的组件集时才会很慢,这可能会在分析过程中显示大量时间HTML和垃圾收集。在我的情况下,这是通过对html模板进行预先计算来解决的,而不是依赖于ng-repeat,ng-switch,ng-如果无处不在。
我在小部件中使用了ng-repeat ="小部件"包含窗口小部件类型的ng-switch,以显示任意一组窗口小部件(自定义自包含指令)。用代码替换它以生成特定小部件集的角度模板,加速路由从~10s切换到几乎瞬间。
您可以在上方查看google网上论坛,了解我如何解决我的特定问题的更多信息,或者如果您需要一些具体的建议,请提供有关您的应用的更多信息。
答案 2 :(得分:4)
为了提高生产性能,请阅读以下非常好的单线:
引用AngularJS文档:
默认情况下,AngularJS将有关绑定和作用域的信息附加到DOM节点,并将CSS类添加到数据绑定元素:
由于ngBind,ngBindHtml或{{...}}插值,绑定数据和CSS类ng绑定附加到相应的元素。
如果编译器已创建新范围,则范围和ng-scope或ng-isolated-scope CSS类将附加到相应的元素。然后可以通过element.scope()和element.isolateScope()访问这些范围引用。
Protractor和Batarang等工具需要运行此信息,但您可以在生产中禁用此信息,以便在以下方面显着提升性能:
myApp.config(['$compileProvider', function ($compileProvider) {
$compileProvider.debugInfoEnabled(false);
}]);
您可以阅读更多详情here
答案 3 :(得分:3)
通常,如果有超过2000个数据绑定处于活动状态,AngularJS将表现不佳,即范围中的2000个项目每个$摘要周期都被检查脏。因此,Ng-repeat对性能有很大的影响;每个重复的项目至少设置两个绑定,不包括项目中使用的任何其他数据或指令。
AngularJS背后的开发人员之一给出了脏检查细节的精彩描述,以及它在这个SO答案中的表现:
https://stackoverflow.com/a/9693933/179024
该答案下面的评论帖是值得一读的,我也会在同一页的答案中分享一些关于它的想法:
答案 4 :(得分:2)
很抱歉将它作为'答案',因为我还没有足够的分数来发表评论。
我们的AngularJS应用程序遇到了类似的问题。使用'batarang'似乎必须处理大量的范围对象,并且它们相关的$ watch表达式会产生性能打嗝。这让我们想知道是否应该使用另一个框架或类似ReactJS的东西来处理“视图”部分。
答案 5 :(得分:2)
尝试避免以下
不要盲目使用ng-click,ng-mouseenter,ng-mouseleave等鼠标事件直到它是一个迫切的需要,尝试通过使用$ event对象以及js的事件传播概念来减少它们的数量
尽可能使用范围。$ digest而不是范围。$ watch,这确保了摘要周期仅在子范围内执行
最重要的!从HTML中删除所有过滤器!
以上所有内容都会在应用程序的所有范围内触发摘要周期,因此即使视图已经渲染为角度也很有可能再次执行无情的摘要循环
答案 6 :(得分:1)
将DOM操作移动到自定义指令和使用大量$ watch的$ watch问题之间的中间点是使用“bind-once”语义。
这对于数据可用时不可变的数据非常有用。见bindonce
答案 7 :(得分:0)
这只是一个链接!这只是我读这篇文章时的一个想法,我还没有探索过这个想法,但是有人可能这样做了,我等着他的回答我的想法。如何使用共享Web工作程序从ui线程中获取大量繁重的处理? https://github.com/h2non/sharedworkers-angular-poc
我的另一个想法是更简单的想法。您的应用会受益于无限滚动吗?我的意思是这些形式可能不适合在屏幕上,它们没有相互连接,所以为什么不在需要时绘制它们呢?将它们装入内存然后相应地绘制它们。
答案 8 :(得分:0)
就像在任何其他性能优化中一样,了解如何分析应用程序以找到真正的瓶颈非常重要。然后你可以逐个解决它们。我通常按以下顺序对抗瓶颈:
我已逐步展示了一个有角度的示例,展示了如何识别每个步骤的瓶颈。 http://bahmutov.calepin.co/improving-angular-web-app-performance-example.html