如何加速AngularJS应用程序?

woe*_*ing 27 performance angularjs

我有一个带有分页网格的AngularJS应用程序(两个嵌套的ng-repeat).一页有大约25x40个输入元素.在制作1000个绑定的开头,分页性能是可以接受的.

但随后页面增长的复杂性:动态类,不同的上下文菜单,网格的每个单元格的条件内容.并且估计有6000个绑定(每个输入元素6个),分页变得无法使用.

我的问题是:我如何处理AngularJS中的性能问题?明显的第一步是衡量.但Chrome Profiler的结果并没有告诉我那么多,远不知道如何继续.

 Self      Total                           Function
-----------------------------------------------------------------
24?ms    2.79?s    angular.js:7997         Scope.$digest
 1?ms       1?ms   controllers.js:365      setViewportData
16?ms     692?ms   angular.js:13968        ngRepeatWatch
 8?ms      22?ms   angular.js:6439         extend.literal
 9?ms    1.22?s    angular.js:14268        ngSwitchWatchAction
16?ms      45?ms   angular.js:12436        ngModelWatch
 0        621?ms   angular-ui-4.0.js:264   initDateWidget
 0         13?ms   angular.js:12859        ngClassWatchAction
 0         70?ms   angular.js:14184        ngStyleWatchAction
 1?ms       5?ms   angular-ui-4.0.js:261   getOptions
 0         16?ms   angular.js:579          copy
 0          1?ms   angular.js:4558         interpolateFnWatchAction
 1?ms       2?ms   angular.js:5981         token.fn.extend.assign
 0         37?ms   angular.js:8151         Scope.$eval
 1?ms       1?ms   angular.js:6137         extend.constant
14?ms      16?ms   angular.js:651          equals
 1?ms       1?ms   angular.js:4939         $interpolate.fn
Run Code Online (Sandbox Code Playgroud)

旁白:'Object.observe()'是否有可能在未来加快速度(忽略'initDateWidget',这显然是一个不同的话题)?

Ben*_*esh 28

你可以做的事情将最大限度地加速你的Angular应用程序,尽可能减少那些绑定.一种方法是创建一个指令,使用DOM操作而不是使用ng-repeats为您构建表.这将减少您必须处理的整体手表的数量,并使这个$ digest更快.

我知道这样做很难看,但是Angular并不真正意味着设置3000多个绑定.因为它做了一个摘要而且它不是一个观察者模式,所以如果有很多设置的话,它确实会减慢速度.

你甚至可以使用混合方法,你仍然使用ng-repeat,但所有的值都放在DOM中,并使用自定义指令中的直接DOM操作,从而避免了所有绑定.


小智 21

如果您还没有这样做,请安装AngularJS Chrome插件,Batarang,它将帮助您确定哪些绑定导致您的悲伤. https://chrome.google.com/webstore/detail/angularjs-batarang/ighdmehidhipcmcojjgiloacoafjmpfk?hl=en

正如另一个答案所暗示的那样,你正在寻找的东西可能是你的桌子的无限滚动设置的一个小例子,你绑定的模型是你在屏幕上显示的子集.

ng-grid组件实现了这一点,可能值得直接使用它或窃取技术. http://angular-ui.github.com/ng-grid/


hcp*_*cpl 19

资源

这篇关于大型列表中angularJS性能的文章很好地概述了性能调优的选项.

以上答案(Batarang插件除外)也在其中提及.这只是该文章中提示的概述.

使用limitTo(分页)减少数据

一个更明显的解决方案是通过减少视图中的项目数来减少绑定量.可以使用limitTo过滤器完成数据的分页ng-repeat.

例如在如何在一个巨大的数据集(angular.js)提高ngRepeat的表现呢?该文章还附有一个jsbin示例.

还要确保不使用内联方法进行数据提供,因为将在每个$ digest上对其进行评估.

<li ng-repeat="item in filteredItems()"> // Bad idea, since very often evaluated.
<li ng-repeat="item in items"> // Way to go! 
Run Code Online (Sandbox Code Playgroud)

使用bindonce删除绑定

另一个明显的解决方案是删除特定元素的绑定.当然这意味着更新不会再反映在视图中.

bindonce解决方案并不仅仅是删除2路结合多了不少.基本上它在删除绑定之前等待绑定值一次.最适合自己阅读.检查bindonce项目以获取详细信息.

在顶部列出的文章中,还有关于使用2个列表的模式的信息.一个用于可视化,一个用作数据源.

使用ng-grid

Ng-grid具有的优点是它只呈现当前可见的元素.更多信息,请访问http://angular-ui.github.io/ng-grid/.

类似地ng-if从DOM树中完全删除隐藏的元素,同时ng-show仅将它们保留在原位但隐藏.考虑到ng-if将再次显示原始副本(原始是关键,而不是更改)元素到位.

过滤提示

这篇文章还有一些过滤列表的好建议.

就像使用ng-show隐藏过滤掉的元素一样,因为这样就不必创建数据的子列表.

另一种技术称为"去抖动用户输入".最后一个选项是等待过滤,直到用户停止输入.包括一个jsfiddle例子.

更多

可以在链接的文章中找到更多提示.那里也列出了资源,所以应该是一个很好的起点.我相信这里列出了最明显的优势和快速获胜.

另一个很好的写作是如何在AngularJS中使用数据绑定?


Jes*_*uez 13

有点晚了但也许这适合你:

https://github.com/Pasvaz/bindonce

你可以在那些无意改变的绑定上使用它,因此$ digest将不再处理它们.


小智 7

在1.3和更高的角度你可以使用::绑定一次,不需要使用其他3方js

<li ng-repeat="item in :: items">
Run Code Online (Sandbox Code Playgroud)

如果项目不会更改,这是很好的,所以你可以绑定它们一次