Using track by in ng-repeat for better list rendering

Loading

When using ng-repeat to iterate over a list, AngularJS tracks each item by its index by default. However, this can lead to poor performance, especially when dealing with large lists. The track by expression provides a way to uniquely identify items, allowing AngularJS to efficiently update only the modified items instead of re-rendering the entire list.


1. The Problem Without track by

By default, AngularJS tracks items in ng-repeat by their array index. This causes issues when items are added, removed, or reordered because AngularJS destroys and recreates all DOM elements, even when only a small change occurs.

Example: ng-repeat Without track by

<ul>
<li ng-repeat="item in items">{{ item.name }}</li>
</ul>

Issue:

  • If items changes, AngularJS removes and recreates all list elements, even if only one item changes.
  • This leads to unnecessary DOM updates and performance degradation.

2. Solution: Using track by for Efficient List Rendering

Adding track by ensures that AngularJS uniquely identifies each item by a specific property (e.g., id), allowing it to update only the changed elements.

Example: ng-repeat With track by

<ul>
<li ng-repeat="item in items track by item.id">{{ item.name }}</li>
</ul>

How It Works:

  • AngularJS now tracks elements using item.id instead of the index.
  • If an item is added, removed, or updated, only that specific item is modified in the DOM.
  • This results in better performance and smoother UI updates.

3. When Should You Use track by?

When dealing with large lists → Prevents unnecessary DOM re-rendering.
When modifying list items dynamically → Ensures AngularJS efficiently updates only changed elements.
When working with objects that have unique identifiers → Helps maintain stable references.


4. Performance Comparison: Without vs. With track by

Scenario 1: Updating an Item Without track by

$scope.items = [
{ id: 1, name: 'Item A' },
{ id: 2, name: 'Item B' },
{ id: 3, name: 'Item C' }
];

$scope.updateItem = function() {
$scope.items[1] = { id: 2, name: 'Updated Item B' }; // Change one item
};
  • Without track by, AngularJS will remove and recreate all list items, even though only one item changed.

Scenario 2: Updating an Item With track by

<ul>
<li ng-repeat="item in items track by item.id">{{ item.name }}</li>
</ul>
  • Now, only the modified item gets updated in the DOM.

5. Common Mistakes to Avoid with track by

Using an index ($index) instead of a unique ID

<li ng-repeat="item in items track by $index">{{ item.name }}</li>

Issue: When items are added or removed, AngularJS still re-renders elements.

Best Practice: Use a Unique Property Like id

<li ng-repeat="item in items track by item.id">{{ item.name }}</li>

Using a non-unique property as a tracking key

<li ng-repeat="item in items track by item.name">{{ item.name }}</li>

Issue: If multiple items have the same name, AngularJS may misidentify them.

Solution: Always Use a Truly Unique Identifier (e.g., id)

<li ng-repeat="item in items track by item.id">{{ item.name }}</li>

6. Summary – Why Use track by?

FeatureWithout track byWith track by
PerformancePoor, entire list re-rendersOptimized, only changed items update
DOM ManipulationUnnecessary element recreationEfficient, minimal changes
List UpdatesSlow when adding/removing elementsFast, only modifies changed items
Best Use CaseSmall static listsLarge dynamic lists

Leave a Reply

Your email address will not be published. Required fields are marked *