لیست های بزرگ را با Angular CDK مجازی سازی کنید

با پیاده‌سازی اسکرول مجازی، فهرست‌های بزرگ را واکنش‌گراتر کنید.

استیون فلوین
Stephen Fluin

فهرست پیمایشی یکی از رایج‌ترین الگوهای رابط کاربری امروزی است، چه مرور یک فید با پیمایش بی‌نهایت در سایت رسانه اجتماعی مورد علاقه‌تان باشد، چه پیمایش در داشبورد یک شرکت. وقتی فهرست‌های پیمایشی بسیار طولانی می‌شوند (صدها، هزاران یا صدها هزار مورد)، عملکرد برنامه می‌تواند تحت تأثیر قرار گیرد.

لیست‌های بزرگ می‌توانند به کندی بارگذاری شوند زیرا برنامه باید تمام داده‌ها را از قبل بارگذاری و رندر کند. همچنین می‌توانند به کندی رندر و پیمایش شوند زیرا هر مورد در لیست می‌تواند شامل داده‌ها، رسانه‌ها و عملکردهای غنی باشد.

کاربران ممکن است هنگام بارگیری یا پیمایش صفحه با مشکلاتی مواجه شوند که منجر به ناامیدی و ترک صفحه می‌شود.

پیمایش مجازی در Angular با استفاده از کیت توسعه کامپوننت

پیمایش مجازی تکنیک اصلی مورد استفاده برای رفع این مشکلات مقیاس است. پیمایش مجازی با ارائه یک نوار پیمایش با اندازه مناسب و امکان پیمایش در لیست بدون نیاز به برنامه برای نگه داشتن کل لیست در حافظه یا رندر آن در صفحه، حس یک لیست بسیار بزرگ را ایجاد می‌کند.

در Angular، پیمایش مجازی توسط کیت توسعه کامپوننت (CDK) ارائه می‌شود. با تغییر نحوه پیمایش در لیست‌ها و با ارائه چند پارامتر پیکربندی اضافی، پیمایش مجازی CDK به طور خودکار رندر مجازی لیست‌های شما را مدیریت می‌کند و عملکرد و پاسخگویی صفحه را بهبود می‌بخشد.

به جای رندر کردن کل لیست به طور همزمان، فقط زیرمجموعه‌ای از آیتم‌هایی که روی صفحه جا می‌شوند (به‌علاوه یک بافر کوچک) رندر می‌شوند. همزمان با پیمایش کاربر، زیرمجموعه جدیدی از آیتم‌ها محاسبه و رندر می‌شود و در صورت نیاز، از DOM موجود دوباره استفاده می‌شود.

ادامه‌ی این پست به نحوه‌ی راه‌اندازی پیمایش مجازی اولیه می‌پردازد. می‌توانید یک مثال کامل از نحوه‌ی کار را در این برنامه‌ی نمونه مشاهده کنید:

تنظیم پیمایش مجازی

ابتدا مطمئن شوید که @angular/cdk را با استفاده از مدیر بسته مورد علاقه خود نصب کرده‌اید. برای نصب آن با استفاده از npm این دستور را در ترمینال اجرا کنید:

npm install --save @angular/cdk

ScrollingModule به برنامه خود اضافه کنید

پس از نصب CDK، ScrollingModule که پیمایش مجازی را مدیریت می‌کند، از پکیج @angular/cdk/scrolling وارد کنید. سپس آن را به آرایه‌ی import ماژول خود اضافه کنید:

import {ScrollingModule} from '@angular/cdk/scrolling';

...
imports: [
  ScrollingModule
...
]
...

ایجاد یک دریچه دید

برای دیدن نحوه‌ی عملکرد این پکیج، سعی کنید کامپوننتی با لیستی از اعداد از ۰ تا ۹۹۹۹۹ ایجاد کنید:

@Component({
  template: `<div *ngFor="let item of list">{{item}}</div>`
})
export class ScrollComponent {
  list = Array.from({length: 100000}).map((_, i) => i);
}

وقتی مرورگر برنامه را رندر می‌کند، باید ۱۰۰۰۰۰ عنصر <div> مجزا را رندر کند. این ممکن است برای گره‌های متنی ساده خوب باشد، اما هرگونه پیچیدگی در قالب تکراری به خوبی مقیاس‌پذیر نیست و هر شنونده رویداد به طور قابل توجهی افزایش می‌یابد.

برای افزودن پیمایش مجازی و جلوگیری از این مشکلات، باید با قرار دادن لیست در یک عنصر <cdk-virtual-scroll-viewport> یک 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 به صورت پویا زیرمجموعه‌هایی از لیست را رندر می‌کند، باید ارتفاع viewport را با CSS استاندارد مشخص کنید. همچنین باید با مشخص کردن itemSize به viewport در مورد محتوای آن سرنخی بدهید. ماژول از این اطلاعات برای تعیین تعداد آیتم‌هایی که باید در یک زمان معین در DOM نگه داشته شوند و نحوه رندر یک scrollbar با اندازه مناسب استفاده می‌کند.

@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);
}

به جای اینکه کل لیست را پیمایش کند، viewport به صورت پویا زیرمجموعه صحیح لیست را برای کاربر شناسایی و پیمایش می‌کند. اکنون وقتی کاربر صفحه را بارگذاری می‌کند، CDK باید زیرمجموعه‌ای از لیست را که روی صفحه نمایش جا می‌شود (به‌علاوه کمی بافر) رندر کند و هرگونه رویداد پیمایش در viewport زیرمجموعه مناسب لیست را بارگذاری و رندر می‌کند:

CDK زیرمجموعه‌های یک لیست را همزمان با اسکرول کردن کاربر رندر می‌کند.

رفتن بیشتر

قابلیت‌های اسکرول مجازی CDK بسیار فراتر از این مثال ساده است. در برنامه نمونه ، کل لیست در حافظه بود، اما این لیست می‌توانست در صورت نیاز برای برنامه‌های پیچیده‌تر فراخوانی شود. می‌توانید با مطالعه‌ی بخش Scrolling در مستندات CDK ، اطلاعات بیشتری در مورد سایر قابلیت‌های ScrollingModule و دستورالعمل cdkVirtualOf کسب کنید.