Wirtualizacja dużych list za pomocą Angular CDK

Zwiększ responsywność dużych list, stosując przewijanie wirtualne.

Stephen Fluin
Stephen Fluin

Lista przewijana jest jednym z najpopularniejszych obecnie wzorów interfejsu użytkownika, niezależnie od tego, czy chodzi o przeglądanie niekończącego się strumienia w ulubionej sieci społecznościowej, czy też poruszanie się po panelu administracyjnym w firmie. Gdy listy stają się bardzo długie (są na nich setki, tysiące lub setki tysięcy elementów), wydajność aplikacji może się pogorszyć.

Wczytywanie dużych list może być powolne, ponieważ aplikacja musi najpierw wczytać i renderować wszystkie dane. Mogą one też wolno się renderować i przechodzić , ponieważ każdy element na liście może zawierać bogate dane, multimedia i funkcje.

Użytkownicy mogą mieć problemy z wczytywaniem lub przewijaniem strony, co może powodować frustrację i opuszczanie strony.

Wirtualne przewijanie w Angularze za pomocą pakietu CDK (Component Dev Kit)

Wirtualne przewijanie to główna technika stosowana do rozwiązywania tych problemów związanych z skalowaniem. Wirtualne przewijanie daje wrażenie bardzo długiej listy, ponieważ zapewnia pasek przewijania o odpowiedniej wielkości oraz możliwość poruszania się po liście bez konieczności przechowywania jej w pamięci aplikacji lub renderowania na stronie.

W Angular przewijanie wirtualne zapewnia pakiet Component Dev Kit (CDK). Modyfikując sposób iteracji przez listy i podając kilka dodatkowych parametrów konfiguracji, możesz automatycznie zarządzać wirtualnym przewijaniem list w CDK, co poprawia wydajność i szybkość reakcji strony.

Zamiast renderowania całej listy naraz, renderowany jest tylko podzbiór elementów, które mieszczą się na ekranie (oraz niewielki bufor). Gdy użytkownik się przemieszcza, obliczany i renderowany jest nowy podzbiór elementów, przy czym w razie potrzeby wykorzystywany jest istniejący DOM.

Z dalszej części tego artykułu dowiesz się, jak skonfigurować podstawowe przewijanie wirtualne. Pełny przykład działania znajdziesz w tej przykładowej aplikacji:

Konfigurowanie wirtualnego przewijania

Najpierw upewnij się, że masz zainstalowany pakiet @angular/cdk za pomocą ulubionego menedżera pakietów. Aby zainstalować go za pomocą npm, uruchom w terminalu to polecenie:

npm install --save @angular/cdk

Dodawanie ScrollingModule do aplikacji

Po zainstalowaniu CDK zaimportuj ScrollingModule, który obsługuje wirtualne przewijanie, z pakietu @angular/cdk/scrolling. Następnie dodaj go do tablicy importów w module:

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

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

Tworzenie widocznego obszaru

Aby sprawdzić, jak działa pakiet,spróbuj utworzyć komponent z prostą listą liczb od 0 do 99 999:

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

Gdy przeglądarka renderuje aplikację, musi renderować 100 tys. pojedynczych elementów <div>. Może to być odpowiednie w przypadku prostych węzłów tekstowych, ale złożoność powtarzanego szablonu nie będzie się skalować, a detektory zdarzeń będą się znacznie mnożyć.

Aby dodać wirtualne przewijanie i uniknąć tych problemów, musisz utworzyć widok, otaczając listę elementem <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);
}

Ponieważ ScrollingModule dynamicznie renderuje podzbiory listy, musisz określić wysokość widocznego obszaru za pomocą standardowego kodu CSS. Musisz też podać przeglądarce podpowiedź dotyczącą zawartości, podając wartość itemSize. Moduł używa tych informacji do określenia, ile elementów ma być przechowywanych w DOM w danym momencie i jak renderować pasek przewijania o odpowiednim rozmiarze.

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

Na koniec przelicz *ngFor na *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);
}

Zamiast przeszukiwać całą listę, widok będzie dynamicznie identyfikować i przeszukiwać odpowiedni podzbiór listy dla danego użytkownika. Gdy użytkownik wczyta stronę, CDK powinien wyrenderować podzbiór listy, który mieści się na ekranie (oraz trochę bufora), a wszystkie zdarzenia przewijania w widocznym obszarze będą wczytywać i renderować odpowiedni podzbiór listy:

Pakiet CDK renderuje podzbiory listy podczas przewijania przez użytkownika.

Więcej informacji

Możliwości wirtualnego przewijania w CDK wykraczają daleko poza ten podstawowy przykład. W aplikacji przykładowej cała lista była w pamięci, ale w przypadku bardziej złożonych aplikacji można ją pobrać na żądanie. Więcej informacji o innych możliwościach ScrollingModule i dyrektywy cdkVirtualOf znajdziesz w dokumentacji CDK.Scrolling

Baner powitalny: Mr Cup / Fabien Barral, Unsplash.