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 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 di 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. Possono anche essere lenti nella visualizzazione e nella navigazione , in quanto ogni elemento nell'elenco può contenere informazioni, contenuti multimediali e funzionalità.

Gli utenti possono riscontrare problemi quando caricano o scorrono la pagina, causando frustrazione e abbandono della pagina.

Scorrimento virtuale in Angular con il Componenti per sviluppatori

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 esplorarlo senza che l'applicazione debba contenere l'intero elenco in memoria o visualizzarlo sulla pagina.

In Angular, lo scorrimento virtuale è fornito dal Componenti per sviluppatori (CDK). Modificando la modalità di iterazione degli elenchi e fornendo un paio di parametri di configurazione aggiuntivi, lo scorrimento virtuale di CDK gestirà automaticamente il rendering virtuale degli elenchi, migliorando le prestazioni e la reattività delle pagine.

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

Il resto di questo post spiega come configurare lo scorrimento virtuale di base. Puoi vedere un esempio funzionante completo 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

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

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

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

Creare un'area visibile

Per vedere 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 nodi di testo semplici, ma qualsiasi complessità nel modello ripetuto non verrà scalata correttamente e i listener di eventi verranno moltiplicati in modo significativo.

Per aggiungere lo scorrimento virtuale ed evitare questi problemi, devi creare un'area visibile racchiudendo 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 tramite CSS standard. Devi anche fornire un suggerimento all'area visibile sui suoi contenuti specificando itemSize. Il modulo utilizza queste informazioni per determinare il numero di elementi da conservare nel DOM in un determinato momento e come visualizzare 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);
}

Invece di ripetere l'iterazione nell'intero elenco, l'area visibile identificherà e ripeterà in modo dinamico il sottoinsieme corretto dell'elenco per l'utente. Ora, quando l'utente carica la pagina, il CDK dovrebbe visualizzare il sottoinsieme dell'elenco che si adatta allo schermo (più un po' di buffer) e qualsiasi evento di scorrimento nell'area visibile verrà caricato e visualizzato nel sottoinsieme appropriato dell'elenco:

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

Ulteriori informazioni

Le capacità di scorrimento virtuale del CDK vanno molto oltre questo esempio di base. Nell'app di esempio, l'intero elenco era in memoria, ma potrebbe essere recuperato on demand per applicazioni più complesse. Per saperne di più sulle altre funzionalità di ScrollingModule e sull'istruzione cdkVirtualOf, leggi informazioni su Scrolling nella documentazione di CDK.

Immagine hero di Mr Cup / Fabien Barral su Unsplash.