Angular 7 Virtual Scroll example – Angular Material CDK


The @angular/cdk/scrolling module with a technique called Virtual Scrolling helps us display a big list of elements efficiently by only rendering the items in view. Virtual Scrolling is different from infinite scroll – where it renders batches of elements and then when user goes to bottom of the list, it renders the rest. In this tutorial, we create many simple examples that show you how to work with Angular 7 Material CDK – Virtual Scrolling.

Related Post: Angular 7 Drag and Drop example – Angular Material CDK

Setup Angular 7 Material CDK

– Run cmd:
npm install @angular/cdk

– Import ScrollingModule into NgModule:

Angular 7 Virtual Scroll

Generate a list of 1000 random number items:

Create Viewport

We use <cdk-virtual-scroll-viewport> directive with *cdkVirtualFor inside (loop same as *ngFor).
To indicate the size of each item (it maybe height or width depending on the orientation of the Viewport), we use itemSize input property.

Style with .cdk-virtual-scroll-content-wrapper (wrapper element that contains the rendered content):


Use Context Variables

With *cdkVirtualFor, we have some context variables: index, count, first, last, even, odd.

With item-alternate style:


Reduce memory on Caching

By default, *cdkVirtualFor caches created items to improve rendering performance.
We can adjusted size of the view cache using templateCacheSize property (0 means disabling caching).

Horizontal Viewport

By default, the orientation of Viewport is vertical, we can change it by setting orientation="horizontal".
Notice that, instead of height, itemSize property in horizontal orienttation specifies width.

We also need to target CSS at .cdk-virtual-scroll-content-wrapper (the wrapper element contains the rendered content).


Custom Buffer Parameters

When using itemSize directive for fixed size strategy, we can set 2 more buffer parameters: minBufferPx & maxBufferPx that calculate the extra content to be rendered beyond visible items in the Viewport:
– if the Viewport detects that there is less buffered content than minBufferPx it will immediately render more.
– the Viewport will render at least enough buffer to get back to maxBufferPx.

For example, we set: itemSize = 20, minBufferPx = 50, maxBufferPx = 200.
The viewport detects that buffer remaining is only 40px (2 items).
40px < minBufferPx: render more buffer.
– render an additional 160px (8 items) to bring the total buffer size to 40px + 160px = 200px >= maxBufferPx.


Angular 7 Virtual Scroll with Specific Data

As well as Array, *cdkVirtualFor can work with DataSource or Observable<Array>.


A DataSource is an abstract class with two methods:
connect(): is called by the Viewport to receive a stream that emits the data array.
disconnect(): will be invoked when the Viewport is destroyed.

In this example, we will create a DataSource with 1000 items, and simulate fetching data from server using setTimeout() function.

Iterating DataSource by *cdkVirtualFor is just like working with an Array:



We create an BehaviorSubject that emit an Array everytime user clicks on Button:

Iterating Observable Data by *cdkVirtualFor is just like working with an Array:


Angular 7 Virtual Scroll trackBy

We create an Observable data that will be changed (sorted):

To check trackBy, we will test 3 cases:
– no trackBy function
trackBy index
trackBy name field

No trackBy function


With trackBy function

trackBy function works the same as the *ngFor trackBy.

trackBy index


trackBy a field


Angular 7 Virtual Scroll Strategy

Instead of using the itemSize directive on the Viewport, we can provide a custom strategy by creating a class that implements the VirtualScrollStrategy interface and providing it as the VIRTUAL_SCROLL_STRATEGY on the @Component.

In the example, our custom strategy class extends FixedSizeVirtualScrollStrategy that implements VirtualScrollStrategy.


Source Code


By grokonez | November 23, 2018.

Related Posts

3 thoughts on “Angular 7 Virtual Scroll example – Angular Material CDK”

Got Something To Say:

Your email address will not be published. Required fields are marked *