user1943020
user1943020

Reputation:

It's taking almost 5 seconds for the data in my ng-repeat to redraw after I change the source

I have a table on my page that is populated like this:

<tr data-ng-repeat="row in grid.view = (grid.data | filter:isProblemInRange )">

I have the following function:

$scope.gridReset = function () {
   $scope.grid.data = angular.copy($scope.grid.backup);
   $scope.gridForm.$setPristine();
};

The function replaces the data in $scope.grid.data with a backup.

When it runs the angular.copy seems to take no time to run but the data on the screen takes about 5 seconds before I see it changing to the backup copy. Is there anything I could do to speed this up?

Here's the function isProblemInRange:

$scope.isProblemInRange = function (row) {
   return (row.problemId >= $scope.pidLower || $scope.pidLower == null || $scope.pidLower == "") &&
           (row.problemId < $scope.pidUpper || $scope.pidUpper == null || $scope.pidUpper == "")
};

I have approximately 500 rows in the grid.data

Upvotes: 2

Views: 169

Answers (1)

Ilan Frumer
Ilan Frumer

Reputation: 32377

1. Does your data has to be bound only once for each change?

  • ng-repeat sets a $watch for each item and within each $digest it dirty checks all registered $$watchers. If you have 2000+ of these $$watchers then your application will not be responsive (maybe until object.observe) and there is no way to fix it without reducing the amount of registered $$watchers.
  • You must read @Misko Hevery's answer: How does data binding work in AngularJS?
  • Check bindonce if it suites your requirements: https://github.com/Pasvaz/bindonce

2. If you have indexes then you can help ng-repeat.

  • ng-repeat without track by removes all DOM elements every time your array/object is overridden just to recreate all DOM elements again. If you have 1000+ elements that is slowwwwww.
  • angular.js 1.2 introduced track by syntax for ng-repeat to solve this issue.
  • Check this article : Using Track By With ng-Repeat In Angular.js 1.2

3. If you must have a huge amount of dynamic bindings?

what ng-repeat watches?

ng-repeat uses $scope.$watchCollection, from the docs:

$watchCollection(obj, listener)

Shallow watches the properties of an object and fires whenever any of the properties change (for arrays, this implies watching the array items; for object maps, this implies watching the properties). If a change is detected, the listener callback is fired.

That means if you have an array with 1000 objects ([1..1000]) then you end up with 1000 dirty checks with each $digest, one for each item(property).

ng-repeat and the DOM

  • If you override the collection object itself (grid.data in the question above), all elements are removed from the DOM (unless you use track by) because by default, ng-reapet uses $$hashkeys for tracking changes. Those $$hashkeys are lost whenever the collection is replaced.
  • If items are removed or added to the array without overriding it, then only these items are removed / added to the DOM.

Upvotes: 2

Related Questions