כדי לשפר את מהירות התגובה של רשימות גדולות, כדאי להטמיע גלילה וירטואלית.
רשימה עם גלילה היא אחד מדפוסי ממשק המשתמש הנפוצים ביותר כיום, בין אם מדובר בגלילה בפיד אינסופי באתר המדיה החברתית האהוב עליכם או בניווט בלוח בקרה של ארגון. כשמגלגלים ברשימות ארוכות מאוד (מאות, אלפים או מאות אלפים של פריטים), הביצועים של האפליקציה עלולים להיפגע.
טעינה של רשימות גדולות עלולה להיות איטית כי האפליקציה צריכה לטעון את כל הנתונים ולעבד אותם מראש. יכול להיות שייקח זמן עד שהם יוצגו ועד שתוכלו לנווט בהם , כי כל פריט ברשימה יכול לכלול מידע מגוון, מדיה ופונקציונליות.
משתמשים עלולים להיתקל בבעיות כשהם טוענים את הדף או גוללים בו, מה שמוביל לתסכול ולעזיבת הדף.
גלילה וירטואלית ב-Angular באמצעות Component Dev Kit
גלילה וירטואלית היא הטכניקה העיקרית שמשמשת לפתרון בעיות שקשורות לקנה מידה. גלילה וירטואלית יוצרת את הרושם של רשימה גדולה מאוד, כי היא מספקת פס גלילה בגודל מתאים ומאפשרת לנווט ברשימה בלי שהאפליקציה תצטרך לשמור את כל הרשימה בזיכרון או לעבד אותה בדף.
ב-Angular, גלילה וירטואלית מסופקת על ידי 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> נפרדים. זה יכול להיות בסדר לצמתי טקסט בסיסיים, אבל אם יש מורכבות בתבנית החוזרת, היא לא תתרחב בצורה טובה, ומאזיני אירועים יוכפלו באופן משמעותי.
כדי להוסיף גלילה וירטואלית ולמנוע את הבעיות האלה, צריך ליצור אזור תצוגה על ידי הוספת רשימה לרכיב <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.