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
?
Feature | Without track by | With track by |
---|---|---|
Performance | Poor, entire list re-renders | Optimized, only changed items update |
DOM Manipulation | Unnecessary element recreation | Efficient, minimal changes |
List Updates | Slow when adding/removing elements | Fast, only modifies changed items |
Best Use Case | Small static lists | Large dynamic lists |