2013-03-26 67 views
24

我有一个带分页网格的AngularJS应用程序(两个嵌套的ng-repeat)。一页有大约25x40的输入元素。在发布1000次绑定的开始时,分页性能可以接受。如何加速AngularJS应用程序?

但是,页面的复杂度增长:动态类,变化的上下文菜单,网格的每个单元的条件内容。估计有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 

旁白:有没有可能是“Object.observe()”将在未来加快东西(忽略“initDateWidget”,这显然是一个不同的主题)?

+0

我曾在这里这个问题,以帮助人们加快NG2应用提高性能一般,它应该能为您提供一些见解:https://开头计算器。 com/questions/42583421/how-to-compress-and-optimize-an-angular2-application – HappyCoder 2017-07-06 11:35:49

回答

27

你可以做的事情将最快加速你的Angular应用程序是减少那些绑定,你可以。做到这一点的一种方法是创建一个指令,使用DOM操作为您创建表格,而不是使用ng-repeats。这将减少您必须处理的整体手表数量,并使该消化速度快得多。

我知道这样做很丑陋,但Angular并非真正意义上要设置3000+个绑定。既然它做了一个摘要,它不是一个观察者模式,它确实减慢了许多设置的东西。

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

20

如果您还没有这样做,请安装AngularJS Chrome的插件,Batarang,这将帮助你找出其中你绑定的是你造成的悲伤。 https://chrome.google.com/webstore/detail/angularjs-batarang/ighdmehidhipcmcojjgiloacoafjmpfk?hl=en

至于对方的回答表明,你要找什么是可能在模型绑定到的子集你在屏幕上显示无限滚动设置为你的表的一个小案例。

的NG-网格组件实现这一点,可能是值得考虑的要么直接使用或窃取的技术。 http://angular-ui.github.com/ng-grid/

+0

多么棒的工具!谢谢,谢谢,谢谢!这应该安装在每台开发人员计算机上;-) – Sebastian 2014-01-04 12:56:27

+0

不错的工具,但它仍然表明ngModelWatch占用了总时间的91.9%,所以真正的准确定位很困难,也许我以错误的方式使用它 – Highmastdon 2014-10-14 09:19:45

13

有点晚,但也许这对你的作品:

https://github.com/Pasvaz/bindonce

您可以使用它在这些绑定是注定不会改变,因此$消化将不会处理它们了。

18

资源

This post about angularJS performance on large lists有你有选择性能调优很好的概述。

以上答案(除Batarang插件)也提到以内。这只是该文中提示的概述。

减少数据与limitTo(分页)

一个比较明显的解决方案是通过减少您的视图中的项目数量,减少绑定的量。数据的分页可以通过ng-repeat上的limitTo过滤器完成。

例在How to improve performance of ngRepeat over a huge dataset (angular.js)?那篇文章也a jsbin example联系。

另外,还要确保不使用数据,因为这提供了一个内联方法每$摘要进行评估。

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

与bindonce

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

bindonce解决方案不仅仅是去除2路绑定。基本上它会在绑定被移除之前等待绑定的值。最好为自己阅读。详情请查询the bindonce project

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

使用NG网

Ng-grid的优点是,它只是使当前可见的元素。阅读更多在http://angular-ui.github.io/ng-grid/

类似ng-if完全从DOM树中移除隐藏的元素,而ng-show只能将它们保留在原位但隐藏。考虑到ng-if会在再次显示时放置原件的副本(原件是钥匙,而不是更改)。

过滤提示

该文章还有一些很好的过滤列表提示。

喜欢使用ng-show隐藏因为这种方式不具有子列表的数据的要创建的过滤元件。

而另一种称为“去抖用户输入”的技术。最后一个选项是等待过滤,直到用户停止输入。包括a jsfiddle example

更多

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

另一篇精辟论述是How does data binding work in AngularJS?

6

在1.3角,更可以通过使用::无需绑定,一旦使用其他3方JS

<li ng-repeat="item in :: items"> 

这是一件好事,如果项目不会改变所以你可以绑定他们一次

1

我所遇到的性能问题的数量,当听众的数量在数据网格组件exceded 1000+的技术总结。

我解决了这个问题,使用一个使用react.js构建我的视图的指令。 该指令暴露了更新函数。

每当数据改变(在控制器中)时,更新函数触发指令,然后react.js引擎高效地执行渲染。

我知道在角度项目中使用第二个主要框架是一个很大的开销,这不是真正的数据绑定魔法。但其工作速度更快。

最终我停止使用angular.js并移动到react.js + FLUX。我认为它更好,但我知道它不容易从角度转移,但它的价值。

Angular directive that uses react.js

0

我有性能问题NG-电网大数据,它是由与Angular Grid替换它解决。该网站上的演示显示,它可以轻松管理100,000行。

0

我已经为此摔了几周。我发现两件事情有很大的不同:

(i)一次绑定:在你可以的地方使用一次性绑定; (ii)DEBOUNCE:对于我不需要立即传播的输入,但可以等待250ms,设置去抖设置。这对我的大型ng-repeat表格造成了不可思议的差异。我不能强调反弹设置的有效性。 (请参阅:https://docs.angularjs.org/api/ng/directive/ngModelOptions

0

bject.observe()是一种用于将真正的数据绑定到浏览器的建议机制。它暴露了观察对象和数组变化的机制,并通知其他对这些对象进行的变化。

<!DOCTYPE html> 
<html> 
<head> 
<base target="_blank"> 
<title>Object.observe()</title> 

<link rel="stylesheet" href="../css/main.css" /> 

</head> 

<body> 

<div id="container"> 

    <h1><a href="https://shailendrapathakbits.wordpress.com/" title="code_lab_by_shail ">code_lab_by_shail</a> Object.observe()</h1> 

    <p>An object <code>o</code> is created and <code>Object.observe()</code> is called on it.</p> 

    <p>Three changes are made to <code>o</code> and <code>Object.observe()</code> records these changes as shown below.</p> 

    <p>Use the console to find out what happens if you make further changes to <code>o</code>: it's defined in global scope.</p> 

    <p>Call <code>Object.unobserve(o, observer)</code> to stop observing changes.</p> 

    <p id="data" style="font-size: 14px;"></p> 

    <script src="js/main.js"></script> 

    <a href="https://github.com/shailendra9/objectobserver/blob/master/index.html" title="View source for this page on GitHub" id="viewSource">View source on GitHub</a> 

</div> 

<script src="../js/lib/ga.js"></script> 

</body> 
</html>