Skip to content

Instantly share code, notes, and snippets.

@pcheek
Last active August 29, 2015 14:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pcheek/87d612bd50e10d896267 to your computer and use it in GitHub Desktop.
Save pcheek/87d612bd50e10d896267 to your computer and use it in GitHub Desktop.
Significantly improve the performance of list groups in an AngularJS app by replacing nested ngRepeat directives with $index tracking and conditional comparisons.
<!--
AngularJS List Group Performance Improvements
Suppose you have an array of items which you would like to group by date.
One of the most straightforward approachs to achieving grouped items is to
use nested ng-repeat directives and the groupBy filter in angular-filter:
https://github.com/a8m/angular-filter#groupby
Here is an example:
-->
<div ng-repeat="(date, dailyItems) in filteredItems =
(items | filter: someFilter | groupBy: 'date' |
toArray: true | orderBy: 'date')">
<div class="date">
{{dailyItems.$key | date: 'EEEE, MMMM d, yyyy'}}
</div>
<div class="item" ng-repeat="item in dailyItems">
[...]
</div>
</div>
<!--
However, when coupled with additional filters, and the requirement that
orderBy also be used to correctly order the groups of items, you will
find that performance decreases significantly as a result of the nested
ng-repeat directives and the number of watches that are bound to the view.
Leveraging the additional performance benefits of 'track by' augmentation
for ngRepeat, we can compare the loop's current item with the previous
item in the loop. Simply, if the current item does not have the same date
as the previous item, render a new "group". Since the items have not been
grouped in a nested array, there may not be a need for the orderBy filter.
Here is an example:
-->
<div ng-repeat="item in filteredItems =
(items | filter: someFilter | orderBy: 'date')
track by $index">
<div
class="date"
ng-if="item.date != filteredItems[$index-1].date">
{{item.date | date: 'EEEE, MMMM d, yyyy'}}
</div>
<div class="item">
[...]
</div>
</div>
<!--
Although this solution may not meet the needs of more complicated use
cases, by removing the angular-filter dependency as well as the second
ng-repeat directive we were able to improve performance significantly.
-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment