How to improve performance of ngRepeat over a huge dataset (angular.js)? How to improve performance of ngRepeat over a huge dataset (angular.js)? angularjs angularjs

How to improve performance of ngRepeat over a huge dataset (angular.js)?


I agree with @AndreM96 that the best approach is to display only a limited amount of rows, faster and better UX, this could be done with a pagination or with an infinite scroll.

Infinite scroll with Angular is really simple with limitTo filter. You just have to set the initial limit and when the user asks for more data (I am using a button for simplicity) you increment the limit.

<table>    <tr ng-repeat="d in data | limitTo:totalDisplayed"><td>{{d}}</td></tr></table><button class="btn" ng-click="loadMore()">Load more</button>//the controller$scope.totalDisplayed = 20;$scope.loadMore = function () {  $scope.totalDisplayed += 20;  };$scope.data = data;

Here is a JsBin.

This approach could be a problem for phones because usually they lag when scrolling a lot of data, so in this case I think a pagination fits better.

To do it you will need the limitTo filter and also a custom filter to define the starting point of the data being displayed.

Here is a JSBin with a pagination.


The hottest - and arguably most scalable - approach to overcoming these challenges with large datasets is embodied by the approach of Ionic's collectionRepeat directive and of other implementations like it. A fancy term for this is 'occlusion culling', but you can sum it up as: don't just limit the count of rendered DOM elements to an arbitrary (but still high) paginated number like 50, 100, 500... instead, limit only to as many elements as the user can see.

If you do something like what's commonly known as "infinite scrolling", you're reducing the initial DOM count somewhat, but it bloats quickly after a couple refreshes, because all those new elements are just tacked on at the bottom. Scrolling comes to a crawl, because scrolling is all about element count. There's nothing infinite about it.

Whereas, the collectionRepeat approach is to use only as many elements as will fit in viewport, and then recycle them. As one element rotates out of view, it's detached from the render tree, refilled with data for a new item in the list, then reattached to the render tree at the other end of the list. This is the fastest way known to man to get new information in and out of the DOM, making use of a limited set of existing elements, rather than the traditional cycle of create/destroy... create/destroy. Using this approach, you can truly implement an infinite scroll.

Note that you don't have to use Ionic to use/hack/adapt collectionRepeat, or any other tool like it. That's why they call it open-source. :-) (That said, the Ionic team is doing some pretty ingenious things, worthy of your attention.)


There's at least one excellent example of doing something very similar in React. Only instead of recycling the elements with updated content, you're simply choosing not to render anything in the tree that's not in view. It's blazing fast on 5000 items, although their very simple POC implementation allows a bit of flicker...


Also... to echo some of the other posts, using track by is seriously helpful, even with smaller datasets. Consider it mandatory.


I recommend to see this:

Optimizing AngularJS: 1200ms to 35ms

they made a new directive by optimizing ng-repeat at 4 parts:

Optimization#1: Cache DOM elements

Optimization#2: Aggregate watchers

Optimization#3: Defer element creation

Optimization#4: Bypass watchers for hidden elements

the project is here on github:

Usage:

1- include these files in your single-page app:

  • core.js
  • scalyr.js
  • slyEvaluate.js
  • slyRepeat.js

2- add module dependency:

var app = angular.module("app", ['sly']);

3- replace ng-repeat

<tr sly-repeat="m in rows"> .....<tr>

ENjoY!