Virtualizza elenchi di grandi dimensioni con la CDK di Angular

Rendi gli elenchi di grandi dimensioni più reattivi implementando lo scorrimento virtuale.

Stephen Fluin
Stephen Fluin

L'elenco a scorrimento è uno dei pattern UI più comuni oggi, che si tratti di sfogliare un feed a scorrimento continuo sul tuo sito di social media preferito o di navigare in una dashboard aziendale. Quando gli elenchi a scorrimento diventano molto lunghi (centinaia, migliaia o centinaia di migliaia di elementi), le prestazioni dell'applicazione possono risentirne.

Il caricamento di elenchi di grandi dimensioni può essere lento perché l'applicazione deve caricare ed eseguire il rendering di tutti i dati in anticipo. Inoltre , il rendering e la navigazione possono essere lenti perché ogni elemento dell'elenco può contenere informazioni aggiuntive, contenuti multimediali e funzionalità.

Gli utenti possono riscontrare problemi durante il caricamento o lo scorrimento della pagina, con conseguente frustrazione e abbandono della pagina.

Scorrimento virtuale in Angular con il Component Dev Kit

Lo scorrimento virtuale è la tecnica principale utilizzata per risolvere questi problemi di scalabilità. Lo scorrimento virtuale dà l'impressione di un elenco molto grande, fornendo una barra di scorrimento di dimensioni appropriate e la possibilità di navigare nell'elenco senza richiedere all'applicazione di conservare l'intero elenco in memoria o di eseguirne il rendering sulla pagina.

In Angular, lo scorrimento virtuale è fornito dal Component Dev Kit (CDK). Modificando il modo in cui esegui l'iterazione degli elenchi e fornendo un paio di parametri di configurazione aggiuntivi, lo scorrimento virtuale del CDK gestirà automaticamente il rendering virtuale degli elenchi, migliorando le prestazioni e la reattività della pagina.

Anziché eseguire il rendering dell'intero elenco alla volta, verrà eseguito il rendering solo di un sottoinsieme di elementi che rientrano nello schermo (più un piccolo buffer). Man mano che l'utente naviga, viene calcolato e visualizzato un nuovo sottoinsieme di elementi, riutilizzando il DOM esistente, se necessario.

Il resto di questo post illustra come configurare lo scorrimento virtuale di base. Puoi vedere un esempio completo e funzionante in questa app di esempio:

Configurazione dello scorrimento virtuale

Innanzitutto, assicurati di aver installato @angular/cdk utilizzando il tuo gestore di pacchetti preferito. Per installarlo utilizzando npm, esegui questo comando nel terminale:

npm install --save @angular/cdk

Aggiungi ScrollingModule alla tua app

Una volta installato il CDK, importa ScrollingModule, che gestisce lo scorrimento virtuale, dal pacchetto @angular/cdk/scrolling. Poi aggiungilo all'array di importazioni del tuo modulo:

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

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

Crea un'area visibile

Per vedere come funziona il pacchetto, prova a creare un componente con un elenco di numeri da 0 a 99.999:

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

Quando il browser esegue il rendering dell'app, deve eseguire il rendering di 100.000 singoli elementi <div>. Questo potrebbe andare bene per i nodi di testo di base, ma qualsiasi complessità nel template ripetuto non scala bene e i listener di eventi verranno moltiplicati in modo significativo.

Per aggiungere lo scorrimento virtuale ed evitare questi problemi, devi creare un viewport inserendo l'elenco in un elemento <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);
}

Poiché ScrollingModule esegue il rendering dinamico dei sottoinsiemi dell'elenco, devi specificare l'altezza dell'area visibile con il CSS standard. Devi anche fornire all'area visibile un suggerimento sui suoi contenuti specificando itemSize. Il modulo utilizza queste informazioni per determinare quanti elementi mantenere nel DOM in un determinato momento e come eseguire il rendering di una barra di scorrimento di dimensioni appropriate.

@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);
}

Infine, converti *ngFor in *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);
}

Anziché scorrere l'intero elenco, l'area visibile identifica e scorre dinamicamente il sottoinsieme corretto dell'elenco per l'utente. Ora, quando l'utente carica la pagina, il CDK deve eseguire il rendering del sottoinsieme dell'elenco che si adatta allo schermo (più un po' di buffer) e tutti gli eventi di scorrimento nella finestra visibile caricano ed eseguono il rendering del sottoinsieme appropriato dell'elenco:

Il CDK esegue il rendering di sottoinsiemi di un elenco mentre l'utente scorre.

Andare oltre

Le funzionalità di scorrimento virtuale del CDK vanno ben oltre questo esempio di base. Nell'app di esempio, l'intero elenco era in memoria, ma l'elenco poteva essere recuperato on demand per applicazioni più complesse. Puoi scoprire di più sulle altre funzionalità di ScrollingModule e sulla direttiva cdkVirtualOf leggendo Scrolling nella documentazione di CDK.