Trực quan hoá các danh sách lớn bằng Angular CDK

Giúp các danh sách lớn phản hồi nhanh hơn bằng cách triển khai tính năng cuộn ảo.

Stephen Fluin
Stephen Fluin

Danh sách cuộn là một trong những mẫu giao diện người dùng phổ biến nhất hiện nay, cho dù đó là duyệt xem một nguồn cấp dữ liệu cuộn vô hạn trên trang mạng xã hội yêu thích của bạn hay điều hướng một trang tổng quan của doanh nghiệp. Khi danh sách cuộn trở nên rất dài (hàng trăm, hàng nghìn hoặc hàng trăm nghìn mục), hiệu suất của ứng dụng có thể bị ảnh hưởng.

Danh sách lớn có thể tải chậm vì ứng dụng phải tải và kết xuất tất cả dữ liệu trước. Các thành phần này cũng có thể hiển thị và điều hướng chậm vì mỗi mục trong danh sách có thể có dữ liệu đa dạng thức, nội dung nghe nhìn và chức năng.

Người dùng có thể gặp vấn đề khi tải hoặc cuộn trang, dẫn đến cảm giác khó chịu và rời bỏ trang.

Cuộn ảo trong Angular bằng Bộ công cụ phát triển thành phần

Cuộn ảo là kỹ thuật chính được dùng để giải quyết các vấn đề về tỷ lệ này. Tính năng cuộn ảo tạo cảm giác về một danh sách rất lớn bằng cách cung cấp một thanh cuộn có kích thước phù hợp và khả năng di chuyển trong danh sách mà không yêu cầu ứng dụng phải lưu giữ toàn bộ danh sách trong bộ nhớ hoặc hiển thị danh sách đó trên trang.

Trong Angular, tính năng cuộn ảo được cung cấp bởi Bộ công cụ phát triển thành phần (CDK). Bằng cách sửa đổi cách bạn lặp lại danh sách và cung cấp một vài tham số cấu hình bổ sung, tính năng cuộn ảo của CDK sẽ tự động quản lý việc kết xuất ảo danh sách của bạn, cải thiện hiệu suất và khả năng thích ứng của trang.

Thay vì hiển thị toàn bộ danh sách cùng một lúc, chỉ một nhóm nhỏ các mục vừa với màn hình (cộng với một vùng đệm nhỏ) sẽ được hiển thị. Khi người dùng di chuyển, một nhóm nhỏ các mục mới sẽ được tính toán và hiển thị, sử dụng lại DOM hiện có nếu muốn.

Phần còn lại của bài đăng này sẽ hướng dẫn cách thiết lập tính năng cuộn ảo cơ bản. Bạn có thể xem ví dụ đầy đủ về cách hoạt động trong ứng dụng mẫu này:

Thiết lập tính năng cuộn ảo

Trước tiên, hãy đảm bảo bạn đã cài đặt @angular/cdk bằng trình quản lý gói mà bạn yêu thích. Để cài đặt bằng npm, hãy chạy lệnh này trong dòng lệnh:

npm install --save @angular/cdk

Thêm ScrollingModule vào ứng dụng của bạn

Sau khi cài đặt CDK, hãy nhập ScrollingModule (xử lý thao tác cuộn ảo) từ gói @angular/cdk/scrolling. Sau đó, hãy thêm mô-đun này vào mảng nhập của mô-đun:

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

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

Tạo khung nhìn

Để xem cách hoạt động của gói, hãy thử tạo một thành phần có danh sách số từ 0 đến 99.999:

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

Khi trình duyệt kết xuất ứng dụng, trình duyệt phải kết xuất 100.000 phần tử <div> riêng lẻ. Điều này có thể phù hợp với các nút văn bản cơ bản, nhưng mọi sự phức tạp trong mẫu lặp lại đều không mở rộng được và mọi trình nghe sự kiện sẽ được nhân lên đáng kể.

Để thêm tính năng cuộn ảo và tránh những vấn đề đó, bạn cần tạo một khung nhìn bằng cách gói danh sách trong phần tử <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);
}

Vì ScrollingModule hiển thị linh động các nhóm nhỏ của danh sách, nên bạn phải chỉ định chiều cao của khung nhìn bằng CSS chuẩn. Bạn cũng cần cung cấp cho khung nhìn một gợi ý về nội dung của khung nhìn bằng cách chỉ định itemSize. Mô-đun này sử dụng thông tin này để xác định số lượng mục cần giữ lại trong DOM tại một thời điểm nhất định và cách hiển thị thanh cuộn có kích thước phù hợp.

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

Cuối cùng, hãy chuyển đổi *ngFor thành *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);
}

Thay vì lặp lại toàn bộ danh sách, khung nhìn sẽ tự động xác định và lặp lại tập hợp con chính xác của danh sách cho người dùng. Bây giờ, khi người dùng tải trang, CDK sẽ hiển thị một nhóm nhỏ trong danh sách phù hợp với màn hình (cộng thêm một chút vùng đệm) và mọi sự kiện cuộn trong khung nhìn sẽ tải và hiển thị nhóm nhỏ thích hợp trong danh sách:

CDK hiển thị các nhóm nhỏ của danh sách khi người dùng di chuyển.

Vươn xa hơn

Khả năng cuộn ảo của CDK còn vượt xa ví dụ cơ bản này. Trong ứng dụng mẫu, toàn bộ danh sách đều nằm trong bộ nhớ, nhưng danh sách này có thể được tìm nạp theo yêu cầu đối với các ứng dụng phức tạp hơn. Bạn có thể tìm hiểu thêm về các chức năng khác của ScrollingModule và lệnh cdkVirtualOf bằng cách đọc về Scrolling trong tài liệu về CDK.