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

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

Stephen Fluin
Stephen Fluin

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

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

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

التمرير الافتراضي في Angular باستخدام "مجموعة تطوير المكونات"

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

في 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 إلى 99999:

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

صورة رئيسية من تصوير Mr Cup / "فابيان بارال" على قناة UnLaunch.