Große Listen mit dem Angular CDK virtualisieren

Große Listen lassen sich durch virtuelles Scrollen reaktionsschneller gestalten.

Stephen Fluin
Stephen Fluin

Die Scroll-Liste ist heute eines der häufigsten Benutzeroberflächen-Muster, ganz gleich, ob es um das Durchsuchen eines unendlich scrollbaren Feeds auf Ihrer bevorzugten Social-Media-Website oder das Navigieren in einem Unternehmens-Dashboard geht. Wenn die Scroll-Listen sehr lang werden (Hunderte, Tausende oder Hunderttausende von Elementen), kann dies die Anwendungsleistung beeinträchtigen.

Große Listen können lange dauern, da die Anwendung alle Daten im Voraus laden und rendern muss. Sie können auch langsam gerendert und navigieren , da jedes Element in der Liste Rich-Daten, Medien und Funktionen enthalten kann.

Beim Laden oder Scrollen der Seite können Probleme auftreten, was zu Frustration und Verlassen der Seite führen kann.

Virtuelles Scrollen in Angular mit dem Component Dev Kit

Virtuelles Scrollen ist die primäre Technik, um diese Skalierungsprobleme zu lösen. Virtuelles Scrollen erweckt den Eindruck einer sehr großen Liste, da eine Bildlaufleiste in angemessener Größe angezeigt wird. Außerdem ist es möglich, in der Liste zu navigieren, ohne dass die App die gesamte Liste im Speicher speichern oder auf der Seite rendern muss.

In Angular wird virtuelles Scrollen durch das Component Dev Kit (CDK) bereitgestellt. Indem Sie die Art der Iteration über Listen ändern und einige zusätzliche Konfigurationsparameter bereitstellen, verwaltet das virtuelle Scrollen des CDK das virtuelle Rendering Ihrer Listen automatisch, wodurch die Seitenleistung und die Reaktionszeit verbessert werden.

Anstatt die gesamte Liste gleichzeitig zu rendern, wird nur eine Teilmenge der Elemente, die auf den Bildschirm passen, und ein kleiner Puffer gerendert. Beim Navigieren wird eine neue Teilmenge von Elementen berechnet und gerendert. Dabei wird bei Bedarf das vorhandene DOM wiederverwendet.

Im weiteren Verlauf dieses Beitrags wird beschrieben, wie Sie einfaches virtuelles Scrollen einrichten. In dieser Beispiel-App sehen Sie ein vollständig funktionierendes Beispiel:

Virtuelles Scrollen einrichten

Stelle zuerst sicher, dass du @angular/cdk mit deinem bevorzugten Paketmanager installiert hast. Um es mit npm zu installieren, führen Sie folgenden Befehl im Terminal aus:

npm install --save @angular/cdk

ScrollingModule zur App hinzufügen

Importieren Sie mit dem installierten CDK ScrollingModule aus dem @angular/cdk/scrolling-Paket, das das virtuelle Scrollen verwaltet. Fügen Sie sie dann dem imports -Array Ihres Moduls hinzu:

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

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

Darstellungsbereich erstellen

Um die Funktionsweise des Pakets zu sehen, erstellen Sie eine Komponente mit einer einfachen Liste von Zahlen zwischen 0 und 99.999:

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

Wenn der Browser die App rendert, muss er 100.000 einzelne <div>-Elemente rendern. Bei einfachen Textknoten könnte dies in Ordnung sein, aber die Komplexität in der wiederholten Vorlage lässt sich nicht gut skalieren und die Ereignis-Listener werden erheblich vervielfacht.

Um virtuelles Scrollen hinzuzufügen und diese Probleme zu vermeiden, müssen Sie einen Darstellungsbereich erstellen, indem Sie die Liste in ein <cdk-virtual-scroll-viewport>-Element einschließen:

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

Da ScrollingModule Teilmengen der Liste dynamisch rendert, müssen Sie die Höhe des Darstellungsbereichs über Standard-CSS angeben. Außerdem musst du dem Darstellungsbereich einen Hinweis zum Inhalt geben, indem du itemSize angibst. Anhand dieser Informationen ermittelt das Modul, wie viele Elemente zu einem bestimmten Zeitpunkt im DOM bleiben sollen und wie eine Bildlaufleiste in angemessener Größe gerendert werden soll.

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

Konvertieren Sie abschließend *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);
}

Anstatt die gesamte Liste zu durchlaufen, wird im Darstellungsbereich dynamisch die richtige Teilmenge der Liste für den Nutzer identifiziert und iteriert. Wenn der Nutzer nun die Seite lädt, sollte der CDK die Teilmenge der Liste rendern, die auf den Bildschirm passt (zuzüglich etwas Puffer), und alle Scroll-Ereignisse im Darstellungsbereich werden geladen und die entsprechende Teilmenge der Liste rendern:

Die CDK-Rendering-Teilmengen einer Liste, wenn der Nutzer scrollt.

Noch mehr

Die virtuellen Scrollfähigkeiten des CDK gehen weit über dieses einfache Beispiel hinaus. In der Beispiel-App befand sich die gesamte Liste im Arbeitsspeicher, konnte aber bei komplexeren Anwendungen bei Bedarf abgerufen werden. Weitere Informationen zu den anderen Funktionen von ScrollingModule und der Anweisung cdkVirtualOf finden Sie in der CDK-Dokumentation unter Scrolling.

Hero-Image von Mr Cup / Fabien Barral auf Unsplash