![]()
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
itemschanges, 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.idinstead 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 |
