Virtualiser de grandes listes avec le CDK Angular

Rendez les listes volumineuses plus réactives en implémentant le défilement virtuel.

Stephen Fluin
Stephen Fluin

La liste déroulante est l'un des modèles d'interface utilisateur les plus courants aujourd'hui, qu'il s'agisse de parcourir un flux à défilement infini sur votre site de réseau social préféré ou de naviguer dans un tableau de bord d'entreprise. Lorsque les listes déroulantes deviennent très longues (plusieurs centaines, milliers, voire des centaines de milliers d'éléments), les performances des applications peuvent en pâtir.

Le chargement des listes volumineuses peut être lent, car l'application doit charger et afficher toutes les données à l'avance. Leur affichage et leur navigation peuvent également être lents , car chaque élément de la liste peut comporter des données, des éléments multimédias et des fonctionnalités enrichies.

Les utilisateurs peuvent rencontrer des problèmes lorsqu'ils chargent ou font défiler la page, ce qui peut être source de frustration et d'abandon de page.

Défilement virtuel dans Angular avec le kit de développement de composants

Le défilement virtuel est la principale technique utilisée pour résoudre ces problèmes d'échelle. Le défilement virtuel donne l'impression d'une liste très longue (en fournissant une barre de défilement de taille appropriée) et permet de parcourir la liste sans que l'application ait besoin de conserver la liste complète en mémoire ou de l'afficher sur la page.

Dans Angular, le défilement virtuel est fourni par le kit de développement de composants (CDK). En modifiant la façon dont vous itérez les listes et en fournissant quelques paramètres de configuration supplémentaires, le défilement virtuel du CDK gère automatiquement l'affichage virtuel de vos listes, ce qui améliore les performances et la réactivité des pages.

Au lieu d'afficher la liste complète à la fois, seul un sous-ensemble des éléments pouvant tenir à l'écran (plus une petite mémoire tampon) sera affiché. Au fur et à mesure que l'utilisateur navigue, un nouveau sous-ensemble d'éléments est calculé et affiché, en réutilisant le DOM existant si vous le souhaitez.

La suite de cet article explique comment configurer le défilement virtuel de base. Vous trouverez un exemple fonctionnel complet dans cette application exemple:

Configurer le défilement virtuel

Assurez-vous tout d'abord d'avoir installé @angular/cdk à l'aide de votre gestionnaire de packages favori. Pour l'installer à l'aide de npm, exécutez la commande suivante dans le terminal:

npm install --save @angular/cdk

Ajouter ScrollingModule à votre application

Une fois le CDK installé, importez ScrollingModule, qui gère le défilement virtuel, à partir du package @angular/cdk/scrolling. Ajoutez-le ensuite au tableau "imports" de votre module:

import {ScrollingModule} from '@angular/cdk/scrolling';

...
imports: [
  ScrollingModule
...
]
...

Créer une fenêtre d'affichage

Pour voir comment fonctionne le package, essayez de créer un composant avec une simple liste de nombres compris entre 0 et 99 999:

@Component({
  template: `<div *ngFor="let item of list">{{item}}</div>`
})
export class ScrollComponent {
  list = Array.from({length: 100000}).map((_, i) => i);
}

Lorsque le navigateur effectue le rendu de l'application, il doit afficher 100 000 éléments <div> individuels. Cela peut convenir pour les nœuds de texte simples, mais la complexité du modèle répété ne sera pas adaptée et tous les écouteurs d'événements seront considérablement multipliés.

Pour ajouter le défilement virtuel et éviter ces problèmes, vous devez créer une fenêtre d'affichage en encapsulant la liste dans un élément <cdk-virtual-scroll-viewport>:

@Component({
  template: `<cdk-virtual-scroll-viewport>
    <div *ngFor="let item of list">{{item}}</div>
    </cdk-virtual-scroll-viewport>`
})
export class ScrollComponent {
  list = Array.from({length: 100000}).map((_, i) => i);
}

Étant donné que ScrollingModule affiche dynamiquement des sous-ensembles de la liste, vous devez spécifier la hauteur de la fenêtre d'affichage à l'aide du code CSS standard. Vous devez également fournir un indice sur son contenu à la fenêtre d'affichage en spécifiant le itemSize. Le module utilise ces informations pour déterminer le nombre d'éléments à conserver dans le DOM à un moment donné et comment afficher une barre de défilement de taille appropriée.

@Component({
  template: `<cdk-virtual-scroll-viewport itemSize="18" style="height:80vh">
    <div *ngFor="let item of list">{{item}}</div>
    </cdk-virtual-scroll-viewport>`
})
export class ScrollComponent {
  list = Array.from({length: 100000}).map((_, i) => i);
}

Enfin, convertissez *ngFor en *cdkVirtualFor:

@Component({
  template: `<cdk-virtual-scroll-viewport itemSize="18" style="height:80vh">
    <div *cdkVirtualFor="let item of list">{{item}}</div>
    </cdk-virtual-scroll-viewport>`
})
export class ScrollComponent {
  list = Array.from({length: 100000}).map((_, i) => i);
}

Plutôt que d'itérer la liste complète, la fenêtre d'affichage identifie et itère dynamiquement le sous-ensemble approprié de la liste pour l'utilisateur. Désormais, lorsque l'utilisateur charge la page, le CDK doit afficher le sous-ensemble de la liste qui tient sur l'écran (plus un peu de tampon), et tous les événements de défilement dans la fenêtre d'affichage se chargent et affichent le sous-ensemble approprié de la liste:

Sous-ensembles d'une liste qui sont affichés par le CDK lorsque l'utilisateur fait défiler la page.

Pour aller plus loin

Les capacités de défilement virtuel du CDK vont bien plus loin que cet exemple de base. Dans l'application exemple, la liste complète était en mémoire, mais elle pouvait être récupérée à la demande pour des applications plus complexes. Pour en savoir plus sur les autres fonctionnalités de ScrollingModule et sur la directive cdkVirtualOf, consultez Scrolling dans la documentation du CDK.

Image héros par Mr Cup / Fabien Barral sur Unsplash.