Using track by in ng-repeat for better performance

Loading

Using track by in ng-repeat is an important optimization technique in AngularJS to improve the performance of rendering lists, particularly when dealing with large datasets. By default, AngularJS uses object identity to determine whether a DOM element needs to be re-rendered when the data in an ng-repeat changes. This can lead to unnecessary re-rendering, especially if the data changes frequently or contains large lists of items.

Why use track by?

By default, AngularJS re-renders the entire list of elements whenever the data in the list changes. This is because AngularJS tracks the DOM elements by their identity. When the list is updated, AngularJS compares the current list of elements with the previous one to determine which elements should be added, removed, or updated.

However, this approach can be inefficient if you have a large list and only a small part of the list changes. It may lead to unnecessary DOM manipulations, which could significantly degrade performance.

Using track by allows you to instruct AngularJS to track items in the list by a unique identifier (usually an ID) rather than by their reference or index. This way, AngularJS can efficiently update only the items that have changed, rather than re-rendering the entire list.

How to use track by

The track by keyword is followed by an expression that returns a unique identifier for each item in the list. This identifier helps AngularJS to track and update the correct DOM elements. Here’s an example of how to use track by in ng-repeat:

Basic Example:

Let’s assume you have a list of items where each item has an id and a name. You want to render this list using ng-repeat, and you want AngularJS to track each item by its unique id to avoid unnecessary DOM updates.

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

JavaScript:

angular.module('myApp', [])
.controller('myController', function($scope) {
$scope.items = [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' },
{ id: 3, name: 'Item 3' }
];

// Function to modify the list
$scope.modifyList = function() {
// Modify the list, for example, add or remove an item
$scope.items.push({ id: 4, name: 'Item 4' });
};
});

Explanation:

  • In the example above, ng-repeat="item in items track by item.id" is used. Here, track by item.id tells AngularJS to track each item in the items array by its unique id instead of the default behavior, which is tracking by object identity.
  • This means that if you add, remove, or modify an item, AngularJS will only re-render the affected item in the DOM, rather than the entire list. This results in better performance, especially with large datasets.

When to use track by:

  • Large datasets: When you’re working with large datasets (for example, 1000+ items), track by can significantly improve performance by minimizing DOM manipulations.
  • Dynamic lists: If your list is frequently updated (e.g., adding, removing, or modifying items), using track by ensures that AngularJS can efficiently update only the changed elements rather than re-rendering the entire list.
  • Complex data: If the objects in your list are complex and have many properties, tracking them by a unique identifier (id, for example) avoids unnecessary DOM re-renders when only the data of one object changes.

Avoiding Common Pitfalls

  1. Tracking by the wrong property: Ensure that the property you’re using with track by is always unique for each item. If the property is not unique (e.g., using index or a non-unique value), AngularJS may still re-render unnecessary elements. For example, avoid using: htmlCopyEdit<li ng-repeat="item in items track by $index"> This can cause inefficiency, especially when items are reordered or updated.
  2. track by with dynamic collections: If the collection is dynamic and items are frequently added or removed, using a unique identifier helps AngularJS avoid mistakenly destroying and recreating DOM elements unnecessarily.

Performance Comparison

Without track by, AngularJS will compare the entire list of elements, and if the list is large, this can cause performance issues.

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

With track by:

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

In the case of frequent updates, using track by ensures that only the modified items are updated in the DOM, leading to fewer changes in the DOM and better overall performance.

Example with Dynamic Updates:

Let’s demonstrate the performance improvement with dynamic updates:

<div ng-app="myApp" ng-controller="myController">
<button ng-click="modifyList()">Modify List</button>
<ul>
<li ng-repeat="item in items track by item.id">
{{ item.name }}
</li>
</ul>
</div>

JavaScript:

angular.module('myApp', [])
.controller('myController', function($scope) {
$scope.items = [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' },
{ id: 3, name: 'Item 3' }
];

// Function to modify the list
$scope.modifyList = function() {
// Modify the list, for example, add or remove an item
$scope.items.push({ id: 4, name: 'Item 4' });
};
});

Here, when you click the “Modify List” button, AngularJS will efficiently add a new item without unnecessarily re-rendering the entire list. This is because we’re using track by item.id, so only the new item gets added.

Leave a Reply

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