This article explains how to load a huge chunk of data in HTML page without hampering its performance.
Introduction
VIrtual List in Angular helps in loading a huge chunk of data into view and keeps the DOM consistent. This way, it helps to improve the performance of the UI.
Background
Whenever you are displaying a huge list of data on the Angular UI, you need to implement the pagination which takes a trip to the server to bring every page (for example, 10 data per page), or else a huge chunk of data may cause performance issue on view.
Using the Code
The code uses npm
package of virtual list.
import { VirtualListModule } from 'angular-virtual-list';
import { Component, OnInit } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { ChangeEvent } from 'angular-virtual-list';
export class UserModel {
id: number;
name?: string;
contact?: string;
address?:string;
}
@Component({
selector: 'app-virtuallist',
templateUrl: './virtuallist.component.html',
styleUrls: ['./virtuallist.component.scss']
})
export class VirtuallistComponent implements OnInit {
public items: Array<UserModel>=[];
public scrollList: Array<UserModel>=[];
protected items$ = new BehaviorSubject<UserModel[]>(null);
protected buffer: UserModel[] = [];
protected loading: boolean;
startingItem:number;
enditem:number;
constructor() {
this.setItem();
}
ngOnInit() {
}
protected fetchMore(event: ChangeEvent) {
this.startingItem=event.start+1;
this.enditem= event.end;
if (event.end == this.buffer.length)
return;
}
public setItem() {
for (var i = 0; i <1000000; i++) {
var item = new UserModel()
item.id = i+1;
item.name = "Name " + (i+1).toString();
item.contact="+1 650-253-0000";
item.address=(1600+i+1).toString()+" Amphitheatre Pkwy,
Mountain View, CA 94043, United States";
this.items.push(item);
}
this.items$.next(this.items)
console.log(this.scrollList)
}
}
The HTML view is as given below:
<h2>Total Record Count: {{items.length}}</h2>
<h2 *ngIf="startingItem">{{startingItem}} to {{enditem}} of {{items.length}} are loaded</h2>
<div class="table-like">
<div class="table-head">
<span style="margin-left: 2px; text-align: center;">Id</span>
<span style="margin-left: 50px; text-align: center;">Name</span>
<span style="margin-left: 60px; text-align: center;">Contact Number</span>
<span style="margin-left: 200px;">Address</span>
</div>
<virtual-list
[source$]="items$"
(update)="scrollList = $event"
(end)="fetchMore($event)" height=400>
<div *ngFor="let item of scrollList" style="display: table-row;">
<span style="display: table-cell; padding: 3px 0 0 2px; text-align: center;">
{{item.id}}</span>
<span style="display: table-cell; padding-left: 36px;text-align: center;">
{{item?.name}}</span>
<span style="display: table-cell; padding-left: 36px;">{{item?.contact}}</span>
<span style="display: table-cell; padding-left: 36px;">{{item?.address}}</span>
</div>
</virtual-list>
</div>
The CSS is as follows:
.table-like{
border: 1px solid #9173ff;
width: 900px;
}
.table-head{
color: #fff;
background-color: #6940ff;
border-bottom: 1px solid #9173ff;
}
Whenever user scrolls the list, it will show fixed n number of rows to keep DOM consistent, i.e., if my service is sending an array of 1 million elements and virtual list height is 500 px, then it will display around 10-14 rows of data in the list at a time and on scroll, these rows will be changed with the next or previous elements.
Thus all the time, there will be only 10 to 14 rows in the DOM which keep performance intact.
Points of Interest
You can find the complete code in my GitHub repo at https://github.com/cruse07/AngularTest/.
Look into the virtuallist component.
History
- 24th February, 2020: Initial version