简体   繁体   English

DOM中的元素过多时,Angular ng级性能问题

[英]Angular ng-class performance issue when too many elements in DOM

I have been working on a complex angular page which has been causing performance issue. 我一直在处理导致性能问题的复杂角度页面。 To highlight the problem I have created a fiddle http://jsfiddle.net/4ex2xgL1/3/ here. 为了突出问题,我在这里创建了一个小提琴http://jsfiddle.net/4ex2xgL1/3/

Essentially the performance issue is being caused by ng-class statement which has a function in it. 本质上,性能问题是由其中具有功能的ng-class语句引起的。

<span class="done-{{todo.done}}" ng-class="myfunction()">{{todo.text}}</span>

The span is in an ng-repeat. 跨度为ng-repeat。 On running the fiddle one can see that ng-class gets executed several times when the page loads and on each key up it gets called as many time as number of items in the TODO list. 在运行小提琴时,您可以看到ng-class在页面加载时被执行了几次,并且在每个键上被调用的次数与TODO列表中的项目数一样多。

This is a lot simpler case, in my case I have 780 items on my page and the function ends up being evaluated aroung 3000 times! 这是一个简单得多的案例,以我为例,我的页面上有780个项目,该函数最终被评估了3000次!

One of the solution we saw is to break up the scope but it will cause almost a rewrite of my app. 我们看到的解决方案之一是打破范围,但这几乎会导致我的应用程序被重写。

We also tried https://github.com/Pasvaz/bindonce but it doesn't seem to be working with highly dynamic content. 我们还尝试了https://github.com/Pasvaz/bindonce,但它似乎不适用于高度动态的内容。

Any thoughts? 有什么想法吗?

I built a tree with https://github.com/JimLiu/angular-ui-tree with almost 500 items to render, with quite a lot of listeners. 我用https://github.com/JimLiu/angular-ui-tree构建了一个树,其中包含将近500个要渲染的项目,并且有很多侦听器。 It takes 5 seconds to render. 渲染需要5秒钟。 Bindonce won't work there. Bindonce不会在那里工作。

The only solution out there is make ng-repeat do less. 唯一的解决方案是使ng-repeat减少。 Keep the list small with a pagination, search or anything. 使用分页,搜索或其他方式使列表保持较小。 Its the best shot as far as I know. 据我所知,这是最好的镜头。

Well here are my recommendations 好,这是我的建议

  1. use ng-change on the checkbox to manipulate dom or anything rather using ng-class, it will improve your performance drastically. 在复选框上使用ng-change来操纵dom或其他任何操作,而不是使用ng-class,它将大大提高您的性能。

    <li ng-repeat="todo in todos track by todo.id"> <input type="checkbox" ng-model="todo.done" ng-change="myfunction()"> <span class="done-{{todo.done}}">{{todo.text}}</span> </li>

    http://jsfiddle.net/4ex2xgL1/3/ http://jsfiddle.net/4ex2xgL1/3/

  2. use track by in ng-repeat if you have ids, more here http://www.codelord.net/2014/04/15/improving-ng-repeat-performance-with-track-by/ 如果您有ID,请在ng-repeat中使用track by,更多信息请参见http://www.codelord.net/2014/04/15/improving-ng-repeat-performance-with-track-by/

  3. dont show 780 items in a list. 不要在列表中显示780个项目。 Use a searchbox to show some 100 or 50 or you know better 使用搜索框显示100或50,或者您更了解

  4. quick-ng-repeat not used yet, try testing it https://github.com/allaud/quick-ng-repeat quick-ng-repeat尚未使用,请尝试对其进行测试https://github.com/allaud/quick-ng-repeat

finally a few good http://tech.small-improvements.com/2013/09/10/angularjs-performance-with-large-lists/ 最后一些不错的http://tech.small-improvements.com/2013/09/10/angularjs-performance-with-large-lists/

Finally I found the solution and it will helps lot to improve performance in angular js. 最终,我找到了解决方案,它将大大提高angular js的性能。

If your model changes dynamically and if you have lots of data and then also it improve AngularJS pages rendering up to 1000% and more - no kidding !. 如果您的模型动态变化,并且您有大量数据,那么它也可以将AngularJS页面的显示率提高1000%甚至更多-别开玩笑!

Fore more information you can visit : http://orangevolt.blogspot.in/2013/08/superspeed-your-angularjs-apps.html 有关更多信息,您可以访问: http : //orangevolt.blogspot.in/2013/08/superspeed-your-angularjs-apps.html

Follow the steps: 按照步骤:

  1. download the library from the link: library 从链接下载库:

2.example without library:(check your console) 2.没有库的示例:(请检查您的控制台)

 function MyController( $scope) { var entries = [ { label : 'one', value : 'first entry'}, { label : 'two', value : 'second entry'}, { label : 'three', value : 'third entry'} ]; $scope.label =""; $scope.value =""; $scope.order = 'label'; $scope.add = function() { entries.push({ label : $scope.label, value : $scope.value }); }; $scope.getEntries = function() { console && console.log( "getEntries() called"); return entries; }; } 
 <script src="https://raw.githubusercontent.com/lodash/lodash/2.4.1/dist/lodash.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script> <form name="myform" ng-app ng-controller="MyController"> Label/Value : <input type="text" required ng-model="label"> <input type="text" required ng-model="value"> <button ng-disabled="!myform.$valid" ng-click="add()" >Add</button> <fieldset> <legend> Entries sorted by <select ng-model="order" ng-options="property for property in [ 'label', 'value']"> </select> </legend> <div ng-repeat="entry in getEntries() | orderBy:order"> {{entry.label}} = "{{entry.value}}" </div> </fieldset> </form> 

3.example with library:(check your console) 3.带库的示例:(检查控制台)

 function MyController( $scope) { var entries = [ { label : 'one', value : 'first entry'}, { label : 'two', value : 'second entry'}, { label : 'three', value : 'third entry'} ]; $scope.label =""; $scope.value =""; $scope.order = 'label'; $scope.add = function() { entries.push({ label : $scope.label, value : $scope.value }); // clear cache $scope.getEntries.cache = {}; }; $scope.getEntries = _.memoize( function() { console && console.log( "getEntries() sorted by '" + $scope.order + " 'called"); // return entries sorted by value of $scope.order return _.sortBy( entries, $scope.order); }, function() { // return the cache key for the current result to store return $scope.order; } ); } 
 <script src="https://raw.githubusercontent.com/lodash/lodash/2.4.1/dist/lodash.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.20/angular.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script> <form name="myform" ng-app ng-controller="MyController"> Label/Value : <input type="text" required ng-model="label"> <input type="text" required ng-model="value"> <button ng-disabled="!myform.$valid" ng-click="add()" >Add</button> <fieldset> <legend> Entries sorted by <select ng-model="order" ng-options="property for property in [ 'label', 'value']"> </select> </legend> <div ng-repeat="entry in getEntries()"> {{entry.label}} = "{{entry.value}}" </div> </fieldset> </form> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM