November 27, 2018
Virtual Scrolling in Angular 7
The release of Angular 7 includes a feature that can improve the performance of your application dramatically. Virtual scrolling is highly beneficial when your app has to deal with a lot of data that has to be displayed in tables or lists.
Virtual Scrolling
I could explain what virtual scrolling is, but I couldn’t do it as good as some other folks, so I’m going to recommend that you watch the following talk instead. The first 5 minutes should give you a rough idea.
Angular CDK
The feature is not included in the @angular/core package but is bundled within the Angular CDK.
The Component Dev Kit (CDK) is a set of tools that implement common interaction patterns whilst being unopinionated about their presentation.
https://material.angular.io/cdk/categories
In more simpler terms you could say, that the CDK is the backbone of Angular Material and provides the base functionality without including any styling.
Demo Time
The code we are looking at in this post is hosted on Stackblitz: https://stackblitz.com/edit/angular-virtual-table-scrolling
Start with a plain Angular table
We’re starting with a pretty simple example of a table using a *ngFor loop
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<table> <thead> <tr> <td>Name</td> <td>ID</td> </tr> </thead> <tbody> <tr *ngFor="let row of tableData"> <td>{{row.name}}</td> <td>{{row.id}}</td> </tr> </tbody> </table> |
The tableData property is defined in the corresponding component.ts file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// app.component.ts import { Component, OnInit} from '@angular/core'; @Component({ selector: 'my-app', templateUrl: './app.component.html', styleUrls: [ './app.component.css' ] }) export class AppComponent implements OnInit { name = 'Angular'; tableData = []; ngOnInit() { for (let i = 0; i < 1000; i++) { this.tableData.push({ name: 'Name' + i, id: i }); } } } |
Introducing virtual scrolling
The Angular CDK provides a scrolling component. We’re now going to add it to our plain table in 4 simple steps.
1. Add the dependency
1 2 |
npm install @angular/cdk --save |
2. Add ScrollingModule
1 2 3 4 5 6 7 8 |
//app.module.ts import { ScrollingModule } from '@angular/cdk/scrolling'; @NgModule({ imports: [ ScrollingModule ], }) export class AppModule { } |
3. Add Scrolling Component
Step 2 is to add the <cdk-virtual-scroll-viewport> element around the markup of your table. We need to provide the attribute [itemSize]=”heightOfRowInPx” that tells the scrolling component how high each row is.
4. replace *ngFor with *cdkVirtualFor
instead of using *ngFor we’re going to use *cdkVirtualFor that is needed in order for the virtual scrolling to work as intended.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<cdk-virtual-scroll-viewport [itemSize]="20"> <table> <thead> <tr> <td>Name</td> <td>ID</td> </tr> </thead> <tbody> <tr *cdkVirtualFor="let row of tableData"> <td>{{row.name}}</td> <td>{{row.id}}</td> </tr> </tbody> </table> </cdk-virtual-scroll-viewport> |
Result
If we inspect the DOM changes after introducing the <cdk-virtual-scroll-viewport> we see that the browser is removing and adding DOM Nodes as we are scrolling.

Improvements / Hints
- Depending on the layout of your application you might need to set a height for the <cdk-virtual-scroll-viewport> element
- Use the trackBy function of *ngFor whenever you can like shown here
I want to use virtual scroll for column also. is it possible for nested virtual scroll
[…] Check this out for a full implementation. […]
is there any example without using CDK means custom virtual scrolling component?
can I use it on the whole page not a specific view port – I am trying to avoid scrolling inside the page
That was a great thing I have learnt today.
how does virtual scroling work for nested table
will search work with virtual scrolling??