Angular 7 – Implement Infinite Virtual Scroll in Few Easy Steps in Latest Angular 7.x

In this post, we will discuss one of the major updates in Angular 7 version, its new Virtual scroll feature in CDK which is Material Component Development Kit. Virtual scrolling comes into action where we have a long list of item in applications, the performance of page decreases due to lots of hidden HTML data which are of no use.

Virtual scrolling improves the performance of pages by dynamically rendering only that list data which is visible to the user, as a user scrolls the current set of items replaced by new giving a glimpse of a continuous traditional list.

Let’s get started and create Angular 7 Application with an Infinite virtual scroll.

Also, check Drag and Drop implementation in Angular Material 7

Create new Angular 7 App

We will use Angular CLI to create an application, for that you must have the latest version installed

$ npm install -g @angular/cli

Run following to create a new app

$ ng new Ng7InfiniteVirtualScroll

After running this, CLI will ask for routing and style sheet format. This confirmation is introduced in the latest CLI version.

$ cd Ng7InfiniteVirtualScroll

If you have Visual Studio Code( VS Code ) installed, run following to open in the project in VS Code

$ code .

Open application server on the browser.

$ ng serve --open

Virtual Scrolling Module

To implement Virtual Scrolling, We need to install Angular CDK package and import  ScrollingModule in the application module.

$ npm install @angular/cdk@latest

After the successful install, we will import ScrollingModule in app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

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

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    ScrollingModule,
    PlatformModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

HTML list directive

Now add Virtual Scroll list directive in app.component.html

<cdk-virtual-scroll-viewport itemSize="100">

    <li *cdkVirtualFor="let p of dummydata;" class="animated lightSpeedIn item-wrap">
      <div class="thumbnail-wrap">
          <img src="{{p.avatar}}" />
      </div>
      <div class="info-wrap">
          <h4>{{p.name}}</h4>
          <h6>{{p.company}}</h6>
      </div>
    </li>
  
</cdk-virtual-scroll-viewport>

Here we are implementing virtual scroll, cdk-virtual-scroll-viewport component provides a viewport for virtual scrolling, it must have a property itemSize to define the height of each item in pixels in our virtual list. *cdkVirtualFor is similar to *ngFor and used to loop over the list of object.

There are many other parameters for this directive:

cdkVirtualForTemplate: The template used to stamp out new elements.
cdkVirtualForTrackBy: TheTrackByFunction to use for tracking changes.
viewChange: Emits when the rendered view of the data changes.
Check more supported emit event in the documentation here

In app.component.ts, paste this code

import { Component } from '@angular/core';
import * as faker from 'faker';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  title = 'Ng7InfiniteVirtualScroll';
  dummydata;
  constructor() { 
    this.dummydata = Array(10000)
      .fill(1)
      .map(_ => {
        return {
          name: faker.name.findName(),
          company:faker.company.companyName(),
          avatar:faker.image.avatar()
        };
      });
  }
}

Here we used the faker.js module to generate dummy data of 1000 value object.

You can install faker.js in Angular by running following commands

$ npm install faker --save
$ npm install @types/faker --save

List Item Styling & Animation

We must provide height to cdk-virtual-scroll-viewport and items we are going to show in scroll list, the specified height of viewport and item is required by the component to decide whether to remove or show current item.

Add following in app.component.scss and some additional styling for make cute list 😛

.virtual-scroll-wrap {
    width: 50%;
    margin: auto;
    min-width: 380px
  }
  
  cdk-virtual-scroll-viewport { 
    height: 100vh; 
    li { 
        height: 100px; 
        list-style: none; 
        border: 1px solid #ccc; 
        margin: 10px 30px 
    } 
    .thumbnail-wrap { 
        width: 100px; 
        display: inline-block; 
        img { 
            height: 65px; 
            margin: 18px 14px; 
        } 
    } 
    .info-wrap 
    { 
        vertical-align: top; 
        display: inline-block 
    } 
  }
  
  
  @-webkit-keyframes lightSpeedIn {
    from {
      -webkit-transform: translate3d(100%, 0, 0) skewX(-30deg);
      transform: translate3d(100%, 0, 0) skewX(-30deg);
      opacity: 0
    }
  
    60% {
      -webkit-transform: skewX(20deg);
      transform: skewX(20deg);
      opacity: 1
    }
  
    80% {
      -webkit-transform: skewX(-5deg);
      transform: skewX(-5deg)
    }
  
    to {
      -webkit-transform: translate3d(0, 0, 0);
      transform: translate3d(0, 0, 0)
    }
  }
  
  @keyframes lightSpeedIn {
    from {
      -webkit-transform: translate3d(100%, 0, 0) skewX(-30deg);
      transform: translate3d(100%, 0, 0) skewX(-30deg);
      opacity: 0
    }
  
    60% {
      -webkit-transform: skewX(20deg);
      transform: skewX(20deg);
      opacity: 1
    }
  
    80% {
      -webkit-transform: skewX(-5deg);
      transform: skewX(-5deg)
    }
  
    to {
      -webkit-transform: translate3d(0, 0, 0);
      transform: translate3d(0, 0, 0)
    }
  }
  
  .lightSpeedIn {
    -webkit-animation-name: lightSpeedIn;
    animation-name: lightSpeedIn;
    -webkit-animation-timing-function: ease-out;
    animation-timing-function: ease-out
  }
  
  .animated {
    -webkit-animation-duration: 1s;
    animation-duration: 1s;
    -webkit-animation-fill-mode: both;
    animation-fill-mode: both
  }

Scroll effect lightSpeedIn is used from Animate.css

It’s Done! now run the app running below command

$ ng serve --open

to see it in action. Check working demo here.

Also, check Drag and Drop implementation in Angular Material 7

3 thoughts on “Angular 7 – Implement Infinite Virtual Scroll in Few Easy Steps in Latest Angular 7.x”

    1. There is a semi-colon issue in css just replace the below class it will work fine.
      cdk-virtual-scroll-viewport {
      height: 100vh;
      li {
      height: 100px;
      list-style: none;
      border: 1px solid #ccc;
      margin: 10px 30px
      }
      .thumbnail-wrap {
      width: 100px;
      display: inline-block;
      img {
      height: 65px;
      margin: 18px 14px;
      }
      }
      .info-wrap {
      vertical-align: top;
      display: inline-block
      }
      }

Leave a Comment

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