Große Listen mit dem Angular CDK virtualisieren

Durch virtuelles Scrollen können Sie große Listen reaktionsschneller gestalten.

Stephen Fluin
Stephen Fluin

Die scrollbare Liste ist eines der gängigsten UI-Muster. Sie finden sie beispielsweise in einem endlos scrollbaren Feed in Ihrer bevorzugten Social-Media-Website oder in einem Unternehmens-Dashboard. Wenn Listen sehr lang werden (mit Hunderten, Tausenden oder Hunderttausenden von Elementen), kann die Anwendungsleistung beeinträchtigt werden.

Das Laden großer Listen kann lange dauern, da die Anwendung alle Daten vorab laden und rendern muss. Außerdem kann das Rendern und Navigieren langsam sein , da jedes Element in der Liste umfangreiche Daten, Medien und Funktionen enthalten kann.

Nutzer können beim Laden oder Scrollen der Seite auf Probleme stoßen, was zu Frustration und zum Verlassen der Seite führt.

Virtuelles Scrollen in Angular mit dem Component Dev Kit

Das virtuelle Scrollen ist die primäre Methode, um diese Skalierungsprobleme zu beheben. Durch das virtuelle Scrollen entsteht der Eindruck einer sehr langen Liste, da eine scrollbare Leiste mit angemessener Größe angezeigt wird. Außerdem können Sie sich in der Liste bewegen, ohne dass die gesamte Liste im Arbeitsspeicher gehalten oder auf der Seite gerendert werden muss.

In Angular wird virtuelles Scrollen vom Component Dev Kit (CDK) bereitgestellt. Wenn Sie die Iteration durch Listen ändern und einige zusätzliche Konfigurationsparameter angeben, wird das virtuelle Rendering Ihrer Listen automatisch vom virtuellen Scrollen der CDK verwaltet. So lassen sich die Seitenleistung und die Reaktionsfähigkeit verbessern.

Anstatt die gesamte Liste gleichzeitig zu rendern, wird nur ein Teil der Elemente gerendert, die auf dem Bildschirm passen, sowie ein kleiner Puffer. Wenn sich der Nutzer bewegt, wird eine neue Teilmenge von Elementen berechnet und gerendert. Dabei wird das vorhandene DOM nach Bedarf wiederverwendet.

Im Rest dieses Beitrags erfahren Sie, wie Sie das grundlegende virtuelle Scrollen einrichten. Ein vollständiges funktionierendes Beispiel finden Sie in dieser Beispielanwendung:

Virtuelles Scrollen einrichten

Installieren Sie zuerst @angular/cdk mit Ihrem bevorzugten Paketmanager. Führen Sie zum Installieren mit npm folgenden Befehl im Terminal aus:

npm install --save @angular/cdk

ScrollingModule zu Ihrer App hinzufügen

Nachdem das CDK installiert ist, importieren Sie ScrollingModule, das für das virtuelle Scrollen zuständig ist, aus dem @angular/cdk/scrolling-Paket. Fügen Sie es dann dem Imports-Array Ihres Moduls hinzu:

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

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

Darstellungsbereich erstellen

Um zu sehen, wie das Paket funktioniert,erstellen Sie eine Komponente mit einer einfachen Liste von Zahlen von 0 bis 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. Das ist für einfache Textknoten in Ordnung, aber jede Komplexität in der wiederholten Vorlage lässt sich nicht gut skalieren und alle Ereignis-Listener werden erheblich multipliziert.

Wenn Sie virtuelles Scrollen hinzufügen und diese Probleme vermeiden möchten, 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. Sie müssen dem Viewport auch einen Hinweis auf seinen Inhalt geben, indem Sie die itemSize angeben. Anhand dieser Informationen ermittelt das Modul, wie viele Elemente zu einem bestimmten Zeitpunkt im DOM beibehalten werden sollen und wie eine scrollbare Leiste mit der richtigen 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 durchsuchen, wird im Viewport dynamisch der richtige Teil der Liste für den Nutzer ermittelt und durchsucht. Wenn der Nutzer die Seite jetzt lädt, sollte die CDK den Teil der Liste rendern, der auf dem Bildschirm passt (plus ein wenig Puffer). Bei Scroll-Ereignissen im Darstellungsbereich wird der entsprechende Teil der Liste geladen und gerendert:

Das CDK rendert Teilmengen einer Liste, während der Nutzer scrollt.

Weiterführende Informationen

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

Hero-Image von Mr Cup / Fabien Barral auf Unsplash.