Do you utilize ngFor in Angular to iterate over arrays or collections? If that's the case, you might have come across performance issues or unexpected behavior when updating or deleting items. But fret not! Angular offers a practical solution known as trackBy that can greatly enhance the performance and stability of your ngFor loops. Let's delve into it and learn how to effectively use it.
The Challenge
By default, Angular employs the index of each item in an array to track changes in ngFor loops. This implies that if the array's order changes or items are added or removed, Angular will re-render the entire list. Such a scenario can lead to performance bottlenecks, particularly when dealing with large arrays or complex components within the loop.
The following example shows what happens when we refresh the entire list. The App displays the list of names. it has option to add a name, remove a name and refresh the entire name list.
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
names = new Array<string>();
name: string = '';
ngOnInit() {
this.Refresh();
}
remove(i: number) {
this.names.splice(i, 1);
}
addMovie() {
this.names.push(this.name);
this.name = '';
}
Refresh() {
console.log('refresh');
this.names = ['Manish', 'Rahul', 'Ashish', 'Aditya', 'Rohan'];
}
}
HTML
<p>App Component</p>
<ul>
<li *ngFor="let name of names; index as i">
{{i}}. {{name}} <button (click)="remove(i)">remove</button>
</li>
</ul>
<button (click)="Refresh()">Refresh>/<button> <br/>
Name : <input type="text" [(ngModel)]="name">
<button (click)="addMovie()">Add Name</button>