إنشاء قائمة افتراضية للقوائم الكبيرة باستخدام Angular CDK

يمكنك جعل القوائم الكبيرة أكثر استجابة من خلال تنفيذ ميزة "التمرير الافتراضي".

Stephen Fluin
Stephen Fluin

تُعدّ قائمة التمرير من أكثر أنماط واجهة المستخدم شيوعًا اليوم، سواء كان ذلك لتصفّح خلاصة تمرير لا نهائي على موقع وسائل التواصل الاجتماعي المفضّل لديك أو للتنقّل في لوحة بيانات المؤسسة. عندما تصبح قوائم التمرير طويلة جدًا (مئات أو آلاف أو مئات الآلاف من العناصر)، يمكن أن يتأثر أداء التطبيق.

قد يكون تحميل القوائم الكبيرة بطيئًا لأن التطبيق يجب أن يقوم بتحميل وعرض جميع البيانات مقدمًا. ويمكن أن تكون بطيئة أيضًا في العرض والتنقّل لأنّ كل عنصر في القائمة يمكن أن يتضمّن بيانات وافية ووسائط ووظائف.

يمكن أن يواجه المستخدمون مشاكل عند تحميل الصفحة أو الانتقال للأسفل فيها، ما يؤدي إلى شعورهم بالإحباط ومغادرة الصفحة.

التمرير الافتراضي في Angular باستخدام Component Dev Kit

يُعدّ التمرير الافتراضي الأسلوب الأساسي المستخدَم لحلّ هذه المشاكل المتعلّقة بالحجم. يمنحك التمرير الافتراضي انطباعًا بوجود قائمة كبيرة جدًا، من خلال توفير شريط تمرير بحجم مناسب، والقدرة على التنقل في القائمة بدون مطالبة التطبيق بالاحتفاظ بالقائمة بأكملها في الذاكرة أو عرضها على الصفحة.

في Angular، يتم توفير ميزة "التمرير الافتراضي" من خلال حزمة تطوير المكوّنات (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 العادي. عليك أيضًا تقديم تلميح إلى إطار العرض حول محتواه من خلال تحديد itemSize. تستخدم الوحدة هذه المعلومات لتحديد عدد العناصر التي يجب الاحتفاظ بها في نموذج العناصر في المستند في وقت معيّن وكيفية عرض شريط تمرير بحجم مناسب.

@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 هذا المثال الأساسي بكثير. في نموذج التطبيق، كانت القائمة بأكملها في الذاكرة، ولكن يمكن جلب القائمة عند الطلب للتطبيقات الأكثر تعقيدًا. يمكنك الاطّلاع على مزيد من المعلومات حول الإمكانات الأخرى لـ ScrollingModule والتوجيه cdkVirtualOf من خلال قراءة Scrolling في مستندات CDK.