Zwiększanie responsywności dużych list dzięki wirtualnemu przewijaniu
Przewijana lista to obecnie jeden z najpopularniejszych wzorców interfejsu użytkownika. Możesz go spotkać np. podczas przeglądania nieskończonego kanału w ulubionym serwisie społecznościowym lub podczas poruszania się po panelu firmowym. Gdy przewijane listy stają się bardzo długie (zawierają setki, tysiące lub setki tysięcy elementów), wydajność aplikacji może się pogorszyć.
Duże listy mogą się wolno wczytywać, ponieważ aplikacja musi wczytać i wyrenderować wszystkie dane z góry. Mogą też wolno się renderować i nawigować , ponieważ każdy element na liście może zawierać dane rozszerzone, multimedia i funkcje.
Użytkownicy mogą mieć problemy z wczytywaniem lub przewijaniem strony, co może prowadzić do frustracji i opuszczenia strony.
Wirtualne przewijanie w Angularze za pomocą pakietu CDK (Component Dev Kit)
Wirtualne przewijanie to podstawowa technika stosowana w celu rozwiązania tych problemów ze skalowaniem. Wirtualne przewijanie sprawia wrażenie bardzo długiej listy, ponieważ zapewnia pasek przewijania o odpowiednim rozmiarze i umożliwia poruszanie się po liście bez konieczności przechowywania całej listy w pamięci przez aplikację lub renderowania jej na stronie.
W Angularze wirtualne przewijanie jest obsługiwane przez pakiet CDK (Component Dev Kit). Dzięki modyfikacji sposobu iteracji po listach i podaniu kilku dodatkowych parametrów konfiguracyjnych wirtualne przewijanie CDK będzie automatycznie zarządzać wirtualnym renderowaniem list, co poprawi wydajność i responsywność strony.
Zamiast renderować całą listę naraz, renderowany będzie tylko podzbiór elementów, które mieszczą się na ekranie (plus niewielki bufor). Gdy użytkownik się porusza, obliczany i renderowany jest nowy podzbiór elementów, a w razie potrzeby ponownie używany jest istniejący DOM.
W dalszej części tego posta opisujemy, jak skonfigurować podstawowe wirtualne przewijanie. 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 imports w module:
import {ScrollingModule} from '@angular/cdk/scrolling';
...
imports: [
ScrollingModule
...
]
...
Tworzenie okna widoku
Aby zobaczyć, jak działa pakiet,spróbuj utworzyć komponent z 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 wyrenderować 100 000 pojedynczych <div>
elementów. Może to być w porządku w przypadku podstawowych węzłów tekstowych, ale każda złożoność w powtarzającym się szablonie nie będzie się dobrze skalować, a wszystkie detektory zdarzeń zostaną znacznie pomnożone.
Aby dodać wirtualne przewijanie i uniknąć tych problemów, musisz utworzyć okno widoku
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ść okna widoku za pomocą standardowego CSS. Musisz też podać oknie widoku wskazówkę dotyczącą jego zawartości, określając itemSize. Moduł używa tych informacji, aby określić, 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 przekonwertuj *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 iterować po całej liście, okno widoku dynamicznie identyfikuje i iteruje po odpowiednim podzbiorze listy dla użytkownika. Gdy użytkownik wczytuje stronę, CDK powinien renderować podzbiór listy, który mieści się na ekranie (plus niewielki bufor), a wszystkie zdarzenia przewijania w oknie widoku wczytują i renderują odpowiedni podzbiór listy:
Dalsze kroki
Możliwości wirtualnego przewijania CDK wykraczają daleko poza ten podstawowy przykład. W przykładowej aplikacji, cała lista znajdowała się w pamięci, ale w bardziej złożonych aplikacjach można ją pobierać na żądanie. Więcej informacji o innych możliwościach
ScrollingModule i dyrektywy cdkVirtualOf znajdziesz w dokumentacji Scrolling
CDK w sekcji .