How to increase Angular performance like a pro - part 2

Learn how to use angular ngFor with trackBy function for better perfomance in Angular.

How to increase Angular performance like a pro - part 2

Angular is heavily tailored for developers, we need to be more careful when it come to performance optimisation. The following post will guide you on how to use the ngFor without re-rendering the whole array with trackBy.

ngFor

ngFor is used to render list of items from the given array. let's create a simple topic array and use *ngFor.

<h1>{{title}}</h1>
  <h2>My favorite topic is: {{myTopic}}</h2>
  <p>Topics:</p>
  <ul>
    <li *ngFor="let topic of topics">
      {{ topic }}
    </li>
  </ul>

This will renders mobilelabs trending topics in the list view.

Mobilelabs Trending Topics

My favorite topic is: Angular Pro

Topics:

  • Angular Pro
  • DevOps
  • Terraform
  • Machine Learning

What we are missing here?

Rending an array is very expensive DOM manipulation, When ever new item is added in the array, ngFor directive will destroy the whole <ul></ul> DOM and re-renders again with new list items from the array.

Equality check operator === is used by Angular for detecting the changes between the items in an array. This operator will check for the address change if it is not matched then it will re-render the whole list again.

As we mentioned above, when a new item is added in the array it will create new address for the item in array and it will triggers the Change Strategy run.

What is trackBy

trackBy is closure function for returning a unique identifier for the array item, which will be used for comparing with the address with Equality check operator.

trackBy example

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-topics',
  template: `
    <h1>{{title}}</h1>
    <h2>My favorite topic is: {{myTopic}}</h2>
    <p>Topics:</p>
    <ul>
      <li *ngFor="let topic of topics; trackBy:trackById">
        {{ topic?.name }}
      </li>
    </ul>
  `,
  styleUrls: ['./beta.component.scss']
})
export class TopicsComponent implements OnInit {

  topics: any[];
  constructor() { }

  ngOnInit() {
    this.topics = [
      {
        id: 1112,
        name: 'Angular Pro'
      }, // @ #0x00100
      {
        id: 1113,
        name: 'DevOps'
      }, // @ #0x00200
      {
        id: 1114,
        name: 'Terraform'
      }, // @ #0x00300
      {
        id: 1115,
        name: 'Machine Learning'
      } // @ #0x00400
    ];
  }

  trackById(item) {
    return item.id;
  }

}

it will help to find the truly changed item from the array and manipulates the DOM.

When to use trackBy

If you have simple static array and you don't feel it will affect the performance then you can leave it will just *ngFor but if have larger array and it will be updated dynamically then you should consider trackBy to avoid re-rendering of list.

Summary

We have seen how to use ngFor without re-rendering the list view using trackBy.