כדי לשפר את התגובה של רשימות גדולות, כדאי להטמיע גלילה וירטואלית.
רשימת הגלילה היא אחד מהדפוסים הנפוצים ביותר של ממשק המשתמש כיום, בין אם מדובר בפיד עם גלילה מתמשכת באתר המדיה החברתית המועדף עליכם או בניווט במרכז בקרה של ארגון. כשהרשימות שגלול עליהן ארוכות מאוד (מאות, אלפים או מאות אלפי פריטים), הביצועים של האפליקציה עלולים להיפגע.
טעינת רשימות גדולות עשויה להיות איטית כי האפליקציה צריכה לטעון ולעבד את כל הנתונים מראש. בנוסף, יכול להיות שהעיבוד והניווט בהן יהיו איטיים כי כל פריט ברשימה יכול לכלול נתונים, מדיה ופונקציות עשירים.
משתמשים עלולים להיתקל בבעיות בזמן הטעינה או הגלילה של הדף, מה שעלול לגרום לתסכול ולנטישה של הדף.
גלילה וירטואלית ב-Agular באמצעות Component Dev Kit
גלילה וירטואלית היא הטכניקה העיקרית לפתרון בעיות ההתאמה האלה. גלילה וירטואלית יוצרת את הרושם של רשימה גדולה מאוד – על ידי הצגת סרגל גלילה בגודל מתאים – ומאפשרת לנווט ברשימה בלי שהאפליקציה תצטרך לאחסן את כל הרשימה בזיכרון או להציג אותה בדף.
ב-Agular, הגלילה הווירטואלית מסופקת על ידי Component Dev Kit (CDK). שינוי האופן שבו אתם עוברים על הרשימות והוספת כמה פרמטרים נוספים להגדרה יאפשרו לגלילה הווירטואלית של CDK לנהל באופן אוטומטי את הרינדור הווירטואלי של הרשימות, וכך לשפר את ביצועי הדף ואת תגובה שלו.
במקום להציג את כל הרשימה בכל פעם, המערכת תציג רק קבוצת משנה של הפריטים שמתאימים למסך (פלוס מאגר קטן). כשהמשתמש מנווט, מתבצע חישוב ורינדור של קבוצת משנה חדשה של פריטים, תוך שימוש חוזר ב-DOM הקיים אם רוצים.
בהמשך המאמר נסביר איך להגדיר גלילה וירטואלית בסיסית. אפשר לראות דוגמה שעובדת באופן מלא באפליקציה לדוגמה הזו:
הגדרת גלילה וירטואלית
קודם כול, צריך לוודא שהתקנתם את @angular/cdk
באמצעות מנהל החבילות המועדף עליכם. כדי להתקין אותו באמצעות npm, מריצים את הפקודה הבאה בטרמינל:
npm install --save @angular/cdk
הוספת ScrollingModule
לאפליקציה
לאחר התקנת ה-CDK, אפשר לייבא את ScrollingModule
, שמטפל בגלילה וירטואלית, מהחבילה @angular/cdk/scrolling
. לאחר מכן מוסיפים אותו למערך הייבוא של המודול:
import {ScrollingModule} from '@angular/cdk/scrolling';
...
imports: [
ScrollingModule
...
]
...
יצירת אזור תצוגה
כדי לראות איך החבילה פועלת, ננסה ליצור רכיב עם רשימה פשוטה של מספרים מ-0 עד 99,999:
@Component({
template: `<div *ngFor="let item of list">{{item}}</div>`
})
export class ScrollComponent {
list = Array.from({length: 100000}).map((_, i) => i);
}
כשהדפדפן מעבד את האפליקציה, הוא צריך לעבד 100,000 רכיבי <div>
נפרדים. הפתרון הזה יכול להתאים לצמתים פשוטים של טקסט, אבל כל מורכבות בתבנית החוזרת לא תתאים להתאמה לעומס, וכל פונקציות ה-event listener יוכפלו באופן משמעותי.
כדי להוסיף גלילה וירטואלית ולהימנע מהבעיות האלה, צריך ליצור שדה ראייה על ידי גיבוב הרשימה ברכיב <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);
}
מכיוון ש-ScrollingModule
מעבד באופן דינמי קבוצות משנה של הרשימה, צריך לציין את הגובה של אזור התצוגה באמצעות CSS סטנדרטי. בנוסף, צריך לתת ל-viewport רמז לגבי התוכן שלו על ידי ציון הערך itemSize
. המודול משתמש במידע הזה כדי לקבוע כמה פריטים לשמור ב-DOM בכל זמן נתון ואיך להציג סרגל גלילה בגודל מתאים.
@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);
}
לסיום, ממירים את *ngFor
ל-*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);
}
במקום לעבור על כל הרשימה, חלון התצוגה יזהה באופן דינמי את קבוצת המשנה הנכונה של הרשימה עבור המשתמש ויבצע עליה איטרציה. עכשיו, כשהמשתמש טוען את הדף, ה-CDK צריך לעבד את קבוצת המשנה של הרשימה שמתאימה למסך (עם מאגר נתונים זמני). כל אירועי גלילה באזור התצוגה ייטענו ויעבדו את קבוצת המשנה המתאימה של הרשימה:
מידע נוסף
יכולות הגלילה הווירטואלית של CDK רחבות הרבה יותר מהדוגמה הבסיסית הזו. באפליקציה לדוגמה, הרשימה כולה שמורה בזיכרון, אבל ניתן היה לאחזר את הרשימה על פי דרישה לאפליקציות מורכבות יותר. מידע נוסף על היכולות האחרות של ScrollingModule
ועל ההוראה cdkVirtualOf
זמין במאמר בנושא Scrolling
במסמכי התיעוד של CDK.
התמונה הראשית (Hero) של Mr Cup / Fabien Barral ב-Unsplash.