Quand vous voulez afficher une liste dans un projet Angular, vous utilisez probablement la directive *ngFor.


<ul>
    <li *ngFor= « let book of books »>{{ book.name }}</li>
</ul>


La directive *ngFor instancie un template pour chaque item de la liste.


Quand la liste change (quand par exemple quand vous recevez de nouvelles données du serveur), Angular doit reconstruire toute la liste, car il ne sait pas quel item a été supprimé ou ajouté.


Cela est dû au fait qu'Angular tracke les insertions et suppressions en se basant sur l'identité des objets : même si les données n'ont pas changé, la deuxième réponse du serveur produit de nouveaux objets avec différentes identités !


Cela produit de grosses manipulations du DOM, qui peuvent vite être très coûteuse.



Nous pouvons indiquer à Angular comment tracker les items en lui fournissant une fonction trackBy. Cette fonction prend en paramètre l'index et l'item, et doit retourner un identifiant unique pour cet item.


Voici un exemple d'implémentation de cette fonction pour la liste précédente :


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

@Component({
 selector: "app-root",
 styleUrls: ["./app.component.scss"],
 template: `
  
 <button (click)="getBooks()">Refresh list</button>

 <ul>
  <li *ngFor="let book of books; trackby: trackByFn">{{ book.name }}</li>
 </ul>

 `
})
export class AppComponent implements OnInit {

 public books = [];

 ngOnInit() {
  this.getBooks();
 }

 public getBooks() {
  this.books = this.books.length > 4 ? [
   { id: 0, name: 'Don Quixote - Miguel De Cervantes' },
   { id: 1, name: 'Robinson Crusoe - Daniel Defoe' },
   { id: 2, name: 'Frankenstein - Mary Shelley' },
   { id: 3, name: 'Anna Karenina - Leo Tolstoy' },
  ] : [
   { id: 0, name: 'Don Quixote - Miguel De Cervantes' },
   { id: 1, name: 'Robinson Crusoe - Daniel Defoe' },
   { id: 2, name: 'Frankenstein - Mary Shelley' },
   { id: 3, name: 'Anna Karenina - Leo Tolstoy' },
   { id: 4, name: 'The Trial - Franz Kafka' },
  ];
 }

 public trackByFn(index: number, item) {
  return index;
 }
}


A présent, quand la liste change, Angular peut tracker quel item a été ajouté ou supprimé, en se basant sur l'identifiant unique fourni par la fonction trackBy, et détruit uniquement les items qui ont changé.



Travailler avec des listes de données peut être un sujet sensible côté performance, et l'utilisation de trackBy peut améliorer grandement les choses.