Cải thiện hiệu khi dùng ngFor với trackBy function
Tùy chọn Angular trackBy option giúp cải thiện hiện suất của ngFor nếu danh sách cần hiển thị có nhiều item và liên tục thay đổi.
Trackby trong ngFor
Chúng ta sử dụng ngFor để hiển thị các thành phần có thể lặp lại như mảng trong định dạng danh sách hoặc bảng.
<ol><li *ngFor="let movie of movies;">{{movie.title}} - {{movie.releaseDate}}</li></ol>
Angular tạo 1 phần tử li cho mỗi movie. Vì vậy, nếu có n phần tử, Angular sẽ chèn n node li vào DOM.
Định danh của các phần tử trong trình lặp có thể thay đổi nhưng dữ liệu thì không. Điều này xảy ra khi user thêm, xóa movie, sắp xếp lại danh sách movie theo một thứ tự khác, hoặc đơn giản là làm mới (refresh) lại movie từ backend. Điều này sẽ buộc Angular phải render lại template. Ngay cả khi dữ liệu không thay đổi, phản hồi thứ hai tạo ra các đối tượng có danh tính khác nhau và Angular phải phá bỏ toàn bộ DOM và xây dựng lại nó (như thể tất cả các phần tử cũ đã bị xóa và tất cả các phần tử mới được chèn vào).
Cách dễ nhất để đạt được điều đó là xóa toàn bộ danh sách và hiển thị lại DOM. Nhưng điều này không hiệu quả và nếu danh sách lớn thì đó là một quá trình rất tốn kém.
Để tránh điều đó, Angular sử dụng object identity để theo dõi các phần tử trong danh sách với các node DOM. Do đó, khi bạn thêm hoặc xóa một item, Angular sẽ theo dõi nó và chỉ cập nhật các item đã sửa đổi trong DOM.
Nhưng nếu bạn làm mới (refresh) lại toàn bộ danh sách từ backend, nó sẽ thay thế các đối tượng trong danh sách movies bằng các đối tượng mới. Ngay cả khi các movie giống nhau, Angular cũng không thể phát hiện khi các tham chiếu đối tượng đã thay đổi. Do đó, nó coi chúng là mới và hiển thị lại chúng sau khi phá hủy (destroy) những cái cũ.
Ví dụ sau đây cho thấy điều gì sẽ xảy ra khi chúng ta làm mới toàn bộ danh sách. Ứng dụng sẽ hiển thị danh sách các bộ phim. Nó có tùy chọn để thêm, xóa phim một phim và làm mới toàn bộ phim.
- app.component.ts
- app.component.html
Bạn có thể thấy từ ví dụ trên, Angular render toàn bộ DOM mỗi khi chúng ta nhấp vào nút Refresh.
Trackby
Chúng tôi có thể giải quyết vấn đề này bằng cách cung cấp một function cho tùy chọn trackBy trả về một id duy nhất cho mỗi item. ngFor sẽ sử dụng id duy nhất được trả về bởi hàm trackBy để theo dõi các item. Do đó, ngay cả khi chúng tôi làm mới dữ liệu từ backend, id duy nhất sẽ vẫn giữ nguyên và danh sách sẽ không được render lại.
trackBy nhận một hàm có hai đối số: index và item hiện tại. Nó phải trả về một id nhận dạng duy nhất (uniquely identifies). Ví dụ sau trả về title như id duy nhất (unique id).
Trong template, gán function trackByFn mới tạo cho option trackBy in ngFor:
Trackby multiple fields
Dùng hàm trackByFnMultipleFields cho option trackBy:
Code Example
Reference
Read More