Optimizing Angular Performance with trackBy

Optimizing Angular Performance with trackBy

Optimizing Angular Performance with trackBy

The Problem: Default Behavior of ngFor


The ngFor directive is one of the most commonly used structural directives in Angular. It allows developers to loop over an array or list and display each item in the DOM. However, the default behavior of ngFor comes with some performance caveats.


When Angular loops over a list, it uses "object identity" to track the elements. This means that if you modify or replace items in the list, Angular will re-render the entire DOM list even if only one item has changed. This can result in unnecessary rendering cycles, especially for larger datasets, leading to performance degradation.


Example of Default Behavior

<ul>
  <li *ngFor="let item of items">{{ item.name }}</li>
</ul>


In this simple example, if any changes are made to the items array, Angular will destroy and re-create the entire list, even if only one item was added, removed, or updated.


The Solution: trackBy


To optimize this behavior, Angular provides the trackBy function, which allows you to tell Angular how to uniquely identify each item in the list. This way, Angular can intelligently re-render only the items that have changed, rather than the entire list.


How trackBy Works


The trackBy function returns a unique identifier for each item in the list. This identifier could be an index, an ID, or any other unique property. By providing this identifier, Angular can compare the items more efficiently, reducing the number of DOM updates.


Example with trackBy

Here’s how you can implement trackBy in your Angular application:


<ul>
  <li *ngFor="let item of items; trackBy: trackByFn">{{ item.name }}</li>
</ul>


In the component:


export class AppComponent {
  items = [
    { id: 1, name: 'Item 1' },
    { id: 2, name: 'Item 2' },
    { id: 3, name: 'Item 3' }
  ];

  trackByFn(index: number, item: any): number {
    return item.id; // Use the unique 'id' as the tracking identifier
  }
}


In this example, Angular will now use the id property to track each item in the list. When items are added or removed, Angular will only re-render the specific items that have changed instead of the entire list.


When to Use trackBy


You should consider using trackBy in the following scenarios:

  1. Large Lists: If you are rendering a large list of items (hundreds or thousands), the default behavior of re-rendering the entire list can be expensive. Using trackBy ensures only the necessary DOM updates occur.
  2. Frequently Changing Lists: If your list changes frequently (items being added, removed, or modified), trackBy ensures that Angular only updates the items that have actually changed, reducing unnecessary DOM manipulations.
  3. Complex DOM Structures: If each item in your list has complex DOM structures (e.g., components with nested child components), re-rendering the entire list can be costly. trackBy helps Angular identify the items that don’t need to be re-rendered.


Best Practices


  • Use Unique Identifiers: Ensure that the value returned by trackBy is unique and stable. Usually, using an item's id is a good practice since it's guaranteed to be unique.
  • Avoid Using Index as a Fallback: While it's possible to use the index of the item in the list as a fallback (e.g., trackBy(index)), this can defeat the purpose in some cases. If the order of the list changes, using the index may not prevent re-rendering. Stick to unique properties like IDs when possible.
  • Test with and without trackBy: Not every use of ngFor will require trackBy. For small lists or lists that don’t change often, the performance gains may be minimal. However, for dynamic, large lists, the difference can be significant.



Share Article:
  • Facebook
  • Instagram
  • LinkedIn
  • Twitter
  • Recent Posts