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 có thể 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 có thể 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 quá dài (hàng trăm, hàng nghìn hoặc hàng trăm nghìn mục), hiệu suất ứng dụng có thể bị ảnh hưởng.

Các danh sách lớn có thể tải chậm vì ứng dụng phải tải và hiển thị trước tất cả dữ liệu. Chúng 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ó nhiều 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 phải vấn đề khi tải hoặc cuộn trang, dẫn đến sự thất vọng và việc bỏ qua trang.

Tính năng cuộn ảo trong Angular bằng Component Dev Kit

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 ấn tượng 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 điều hướng danh sách mà không yêu cầu ứng dụng giữ toàn bộ danh sách trong bộ nhớ hoặc kết xuất danh sách đó trên trang.

Trong Angular, tính năng cuộn ảo được cung cấp bởi Component Dev Kit (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 thông số cấu hình bổ sung, tính năng cuộn ảo của CDK sẽ tự động quản lý quá trình kết xuất ảo của danh sách, cải thiện hiệu suất và khả năng phản hồi 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 thêm một vùng đệm nhỏ) sẽ được hiển thị. Khi người dùng di chuyển, một tập hợp con mới gồm các mục 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 thức 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 sau trong thiết bị đầu cuối:

npm install --save @angular/cdk

Thêm ScrollingModule vào ứng dụng

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

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

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

Tạo một khung hiển thị

Để 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 các 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 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 độ phức tạp trong mẫu lặp lại đều không mở rộng tốt 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 hiển thị bằng cách bao bọc danh sách trong một 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);
}

ScrollingModule kết xuất động các tập hợp con của danh sách, nên bạn phải chỉ định chiều cao của khung hiển thị bằng CSS tiêu chuẩn. Bạn cũng cần cung cấp cho khung hiển thị một gợi ý về nội dung của khung 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ữ trong DOM tại một thời điểm nhất định và cách hiển thị một 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 hiển thị sẽ xác định và lặp lại một cách linh động thông qua đúng tập hợp con của danh sách cho người dùng. Giờ đây, khi người dùng tải trang, CDK sẽ hiển thị một phần của danh sách vừa với màn hình (cộng thêm một chút bộ nhớ đệm) và mọi sự kiện cuộn trong khung hiển thị sẽ tải và hiển thị phần thích hợp của danh sách:

CDK hiển thị các tập hợp con 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 nằm trong bộ nhớ, nhưng danh sách 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à chỉ thị cdkVirtualOf bằng cách đọc về Scrolling trong tài liệu về CDK.