Virtualizza elenchi di grandi dimensioni con la CDK di Angular

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

Stephen Fluin
Stephen Fluin

L'elenco scorrevole è uno dei pattern di UI più comuni oggi, che si tratti di sfogliare un feed con scorrimento infinito sul tuo sito di social media preferito o di navigare in una dashboard aziendale. Quando gli elenchi 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 e visualizzare tutti i dati in anticipo. Inoltre , la visualizzazione e la navigazione possono essere lente perché ogni elemento dell'elenco può avere dati, contenuti multimediali e funzionalità avanzati.

Gli utenti possono riscontrare problemi durante il caricamento o lo scorrimento della pagina, il che può causare frustrazione e abbandono della pagina.

Scorri virtuale in Angular con 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 adeguate, e la possibilità di navigare nell'elenco senza che l'applicazione debba memorizzare l'intero elenco in memoria o visualizzarlo nella 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 dei tuoi elenchi, migliorando il rendimento e la reattività della pagina.

Invece di eseguire il rendering dell'intero elenco alla volta, verrà visualizzato solo un sottoinsieme di elementi che si adattano allo schermo (più un piccolo buffer). Mentre l'utente naviga, viene calcolato e visualizzato un nuovo sottoinsieme di elementi, riutilizzando il DOM esistente, se lo si desidera.

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

Configurare lo 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

Aggiungere ScrollingModule all'app

Con il CDK installato, importa ScrollingModule, che gestisce lo scorrimento virtuale, dal pacchetto @angular/cdk/scrolling. Aggiungila all'array imports del modulo:

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

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

Creare un'area visibile

Per capire come funziona il pacchetto, prova a creare un componente con un semplice 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 semplici nodi di testo, ma qualsiasi complessità nel modello ripetuto non sarà scalabile e gli eventuali ascoltatori 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 di sottoinsiemi dell'elenco, devi specificare l'altezza dell'area visibile tramite CSS standard. Devi anche fornire un suggerimento al viewport sui relativi contenuti specificando itemSize. Il modulo utilizza queste informazioni per determinare quanti elementi conservare nel DOM in un determinato momento e come visualizzare una barra di scorrimento delle 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);
}

Invece di eseguire l'iterazione dell'intero elenco, la visualizzazione identifica e sottopone a iterazione dinamica 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 nell'area visibile caricheranno e mostreranno il sottoinsieme appropriato dell'elenco:

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

Per saperne di più

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 poteva essere recuperato su richiesta per applicazioni più complesse. Per scoprire di più sulle altre funzionalità di ScrollingModule e della direttiva cdkVirtualOf, consulta la sezione relativa a Scrolling nella documentazione del CDK.

Immagine hero di Mr Cup / Fabien Barral su Unsplash.