יצירת וירטואליות של רשימות גדולות באמצעות CDK של Angular CDK

משפרים את הרספונסיביות של רשימות גדולות על ידי הטמעת גלילה וירטואלית.

Stephen Fluin
Stephen Fluin

רשימת הגלילה היא אחד מהדפוסים הנפוצים ביותר של ממשק משתמש כיום, בין אם מדובר בגלישה בפיד גלילה מתמשכת באתר המדיה החברתית שלכם או בניווט במרכז הבקרה של הארגון. כאשר רשימות הגלילה נעשות ארוכות מאוד (מאות, אלפים או מאות אלפי פריטים), הביצועים של האפליקציות עלולים להיפגע.

רשימות גדולות עלולות להיות איטיות כי האפליקציה חייבת לטעון ולעבד את כל הנתונים מראש. בנוסף, העיבוד והניווט שלהם עלולים להיות איטיים, מאחר שכל פריט ברשימה יכול לכלול מידע עשיר, מדיה ופונקציונליות.

המשתמשים עלולים להיתקל בבעיות בזמן שהם טוענים או גוללים בדף, דבר שמוביל לתסכול ולנטישה של הדף.

גלילה וירטואלית ב-Agular עם ערכת הפיתוח של הרכיבים

גלילה וירטואלית היא השיטה העיקרית שבה משתמשים כדי לטפל בבעיות מהסוג הזה. גלילה וירטואלית יוצרת רושם של רשימה ארוכה מאוד - על ידי אספקת סרגל גלילה בגודל מתאים - ויכולת לנווט ברשימה מבלי לדרוש מהאפליקציה לאחסן את הרשימה כולה בזיכרון או לעבד אותה בדף.

ב-Angular, גלילה וירטואלית מסופקת על ידי Component Dev Kit (CDK). על ידי שינוי הדרך שבה אתם עוברים בין רשימות, ומתן כמה פרמטרים נוספים של תצורה, הגלילה הווירטואלית של CDK תנהל באופן אוטומטי את הרינדור הווירטואלי של הרשימות שלכם, ותשפר את ביצועי הדף ואת הרספונסיביות.

במקום לעבד את כל הרשימה בבת אחת, יוצגו רק חלק מהפריטים שמתאימים למסך (עם מאגר נתונים זמני קטן). במהלך הניווט של המשתמש, המערכת מחשבת ומעובדת קבוצת משנה חדשה של פריטים, תוך שימוש ב-DOM הקיים לפי הצורך.

שאר הפוסט הזה מסביר איך להגדיר גלילה וירטואלית בסיסית. אפשר לראות דוגמה מלאה לפעולה באפליקציה לדוגמה:

הגדרת גלילה וירטואלית

קודם עליך לוודא שהתקנת את @angular/cdk באמצעות מנהל החבילות המועדף עליך. כדי להתקין אותו באמצעות npm, מריצים את הפקודה הבאה במסוף:

npm install --save @angular/cdk

הוספה של ScrollingModule לאפליקציה

לאחר התקנת ה-CDK, אפשר לייבא מחבילת @angular/cdk/scrolling את ScrollingModule, שמטפל בגלילה וירטואלית. לאחר מכן מוסיפים אותה למערך הייבוא של המודול:

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 רגיל. בנוסף, צריך לספק לאזור התצוגה רמז לגבי התוכן על ידי ציון 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 בזמן שהמשתמש גולל.

להגיע רחוק יותר

יכולות הגלילה הווירטואלית של CDK הן הרבה יותר גדולות מהדוגמה הבסיסית הזו. באפליקציה לדוגמה, הרשימה כולה הייתה בזיכרון, אך ניתן היה לאחזר את הרשימה לפי דרישה לאפליקציות מורכבות יותר. במסמכי התיעוד של CDK אפשר לקרוא מידע נוסף על היכולות האחרות של ScrollingModule ושל ההנחיה cdkVirtualOf בנושא Scrolling.

תמונה ראשית (Hero) של Mr Cup או פביאן באראל ב-UnFlood.