I have been working on a plex angular page which has been causing performance issue. To highlight the problem I have created a fiddle / here.
Essentially the performance issue is being caused by ng-class statement which has a function in it.
<span class="done-{{todo.done}}" ng-class="myfunction()">{{todo.text}}</span>
The span is in an 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.
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!
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 but it doesn't seem to be working with highly dynamic content.
Any thoughts?
I have been working on a plex angular page which has been causing performance issue. To highlight the problem I have created a fiddle http://jsfiddle/4ex2xgL1/3/ here.
Essentially the performance issue is being caused by ng-class statement which has a function in it.
<span class="done-{{todo.done}}" ng-class="myfunction()">{{todo.text}}</span>
The span is in an 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.
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!
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./Pasvaz/bindonce but it doesn't seem to be working with highly dynamic content.
Any thoughts?
Share Improve this question asked Aug 25, 2014 at 7:31 MaheshMahesh 1,0811 gold badge12 silver badges29 bronze badges 4-
In the real app, is the input to
myfunction()
dependent on the current item inng-repeat
? What sort of input does it need to produce a result? Possible solutions will depend on how dynamic the results from that function is. – ivarni Commented Aug 25, 2014 at 7:34 - I would think to do not show 780 items. Show only visible items. Search in Google infinite list – Maxim Shoustin Commented Aug 25, 2014 at 7:35
-
1
The other thing es up in my mind to do not use
ng-class
at all. Create directive instead that will change class regards to your needs (based on user behaviour) – Maxim Shoustin Commented Aug 25, 2014 at 7:37 - @ivarni: we have nested ng-repeat and we have two condtions in ng-class .. if condtion true then myfunction() will be called . in condition we are using parent's ng-repeat and in myfunction() we used ng-repeat child ng-repeat – Mahesh Commented Aug 25, 2014 at 8:12
2 Answers
Reset to default 2I built a tree with https://github./JimLiu/angular-ui-tree with almost 500 items to render, with quite a lot of listeners. It takes 5 seconds to render. Bindonce won't work there.
The only solution out there is make ng-repeat do less. Keep the list small with a pagination, search or anything. Its the best shot as far as I know.
Well here are my remendations
use ng-change on the checkbox to manipulate dom or anything rather using ng-class, it will improve your performance drastically.
<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/4ex2xgL1/3/
use track by in ng-repeat if you have ids, more here http://www.codelord/2014/04/15/improving-ng-repeat-performance-with-track-by/
dont show 780 items in a list. Use a searchbox to show some 100 or 50 or you know better
quick-ng-repeat not used yet, try testing it https://github./allaud/quick-ng-repeat
finally a few good http://tech.small-improvements./2013/09/10/angularjs-performance-with-large-lists/
Finally I found the solution and it will helps lot to improve performance in 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 !.
Fore more information you can visit : http://orangevolt.blogspot.in/2013/08/superspeed-your-angularjs-apps.html
Follow the steps:
- download the library from the link:library
2.example without library:(check your console)
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./lodash/lodash/2.4.1/dist/lodash.js"></script>
<script src="https://ajax.googleapis./ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis./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)
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./lodash/lodash/2.4.1/dist/lodash.js"></script>
<script src="https://ajax.googleapis./ajax/libs/angularjs/1.2.20/angular.min.js"></script>
<script src="https://ajax.googleapis./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>