首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何提高AngularJS应用程序的速度?

如何提高AngularJS应用程序的速度?
EN

Stack Overflow用户
提问于 2013-03-27 01:19:05
回答 11查看 25.4K关注 0票数 27

我有一个带有分页网格的AngularJS应用程序(两个嵌套的ng-repeat)。一个页面大约有25x40个输入元素。在最初进行了1000次绑定时,分页性能是可以接受的。

但随之而来的是页面的复杂性增长:动态类,变化的上下文菜单,网格中每个单元格的条件内容。估计有6000个绑定(每个输入元素6个),分页变得无法使用。

我的问题是:我如何解决AngularJS中的性能问题?显而易见的第一步是衡量。但是Chrome Profiler的结果并没有告诉我那么多,远远不知道如何继续。

代码语言:javascript
运行
复制
 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

旁白:“initDateWidget()”有没有可能在未来加快速度(忽略'Object.observe()‘,这显然是另一个话题)?

EN

回答 11

Stack Overflow用户

回答已采纳

发布于 2013-03-27 01:39:18

你可以做的事情是最大限度地提高你的Angular应用的速度,那就是尽可能地减少这些绑定。要做到这一点,一种方法是创建一个指令,该指令使用DOM操作而不是使用ng-repeats为您构建表。这将减少您必须处理的总监视数量,并使$digest更快。

我知道这样做很丑陋,但是Angular实际上并不是用来设置3000+绑定的。因为它做了摘要,而不是观察者模式,所以在设置了那么多的情况下,它真的会减慢速度。

您甚至可以采用一种混合方法,其中仍然使用ng-repeat,但是所有的值都放在DOM中,使用来自自定义指令的直接DOM操作,从而避免了所有绑定。

票数 28
EN

Stack Overflow用户

发布于 2013-03-30 05:35:12

如果你还没有这样做,请安装AngularJS浏览器插件Batarang,它将帮助你精确定位哪些绑定导致了你的悲痛。https://chrome.google.com/webstore/detail/angularjs-batarang/ighdmehidhipcmcojjgiloacoafjmpfk?hl=en

正如另一个答案所暗示的,您正在寻找的可能是表格的无限滚动设置的一个小例子,其中您绑定到的模型是您在屏幕上显示的子集。

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

票数 21
EN

Stack Overflow用户

发布于 2014-02-12 19:34:04

资源

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链接。

另外,请确保不使用内联方法提供数据,因为它将在每个$digest上求值。

代码语言:javascript
运行
复制
<li ng-repeat="item in filteredItems()"> // Bad idea, since very often evaluated.
<li ng-repeat="item in items"> // Way to go! 

使用bindonce删除绑定

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

bindonce解决方案所做的远不止是移除双向绑定。基本上,在删除绑定之前,它等待值被绑定一次。最好自己读一读。有关详细信息,请查看the bindonce project

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

使用ng-grid

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

Similar ng-if将隐藏的元素从DOM树中完全移除,而ng-show只是将它们保留在适当的位置,但将它们隐藏起来。考虑到ng-if将在再次显示时将原始元素(原始是关键字,而不是更改)的副本放在适当的位置。

过滤提示

这篇文章也有一些关于过滤列表的很好的技巧。

就像使用ng-show隐藏过滤出的元素一样,因为这种方式不需要为数据创建子列表。

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

更多

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

另一篇不错的文章是How does data binding work in AngularJS?

票数 19
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15643467

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档