Ionic 5 Virtual Scroll with Infinite Scroll Loader Tutorial with Example Application

In this Ionic 5/4 tutorial, we’ll discuss how to implement Virtual Scroll on an Infinite Scrolling List in Ionic 5 application.

We’ll combine the Virtual Scroll and Infinite Scroll UI components of the Ionic framework to create an optimized page that can show a large number of items in a List or Grid without any performance issues.

Before we get started let’s have a look at these to components we are going to implement.

What is Virtual Scroll?  How does it work?

A virtual scroll is used on the long lists of items that can fill up page DOM with lots of HTML content to hamper page performance.

The virtual Scroll component loads only a small chunk of items in the DOM which can be accommodated on the viable area with a scroll.

As a user scroll over the list, the current set of list items get replaced by next items. A virtual list creates an illusion of a long list in the scroll but actually it replaces the limited item set with new data.

So it keeps the actual DOM limited on a page and solves the purpose to show long item lists. You will see it working by the end of this tutorial.

 

What is the Infinite Scrolling List? Why it is used?

An Infinite Scrolling list is used to load data items as user scrolls. So that there is no need to click on any button or pagination to see next set of items.

The infinite scroll components take care when the user reaches the bottom of the screen and loads the next set of items to the existing list so that the user keeps on moving without any other trigger.

We limit the data load on the page at once, which is gradually downloaded from a server as user scrolls down by showing a loader spinner icon. This keeps servers less stressed and client-side pages more efficient.

 

Let’s Implement Infinite Scroll lists with Virtual Scroll, the combination of these two can greatly improve and super optimize the performance and provide an easy user experience in parallel.

Install or Update the Ionic CLI

Run the following command to install or update the Ionic CLI package to the latest version

$ npm install -g @ionic/cli

 

Create a new Ionic Application

Execute the following command to create a new Ionic Angular application with a blank template

$ ionic start ionic-virtual-infinite-scroll-list blank --type=angular

Move inside the application directory

$ cd ionic-virtual-infinite-scroll-list

Run application in the lab

$ ionic serve --lab
? Install @ionic/lab? Yes

 

Install FakeJs

What is faker.js?

It provides us mock or randomly generated values which we can use to test application or create fake objects.

To create a list of items using the list UI components, we’ll install the faker module in our Ionic application. Run following npm command to install faker and @types/faker packages

$ npm install faker
$ npm i @types/faker

 

Creating List of Items

Now we’ll create a basic list of items using ion-list and ion-item UI components on the Home page.

In the home.page.html file add following code

<ion-content [fullscreen]="true" class="ion-padding">

  <ion-list>
    <ion-list-header>
      Employee List
    </ion-list-header>

    <ion-item *ngFor="let item of dataList">
      <ion-avatar slot="start">
        <img src="{{item.image}}">
      </ion-avatar>
      <ion-label>
        <h2>{{item.name}}</h2>
        <h3>{{item.address}}</h3>
        <p>{{item.intro}}</p>
      </ion-label>
    </ion-item>
  </ion-list>

</ion-content>

Above we have a simple list of the item created using the ion-list and ion-item components. The ion-item is looping over the provided dataList object using Angular’s *ngFor directive

 

In the home.page.ts file, update class with following code

// home.page.ts
import { Component } from '@angular/core';
import * as faker from 'faker';

@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage {

  dataList = [];

  constructor() {
    this.getEmployees()
  }

  getEmployees() {
    for (let i = 0; i < 250; i++) {
      this.dataList.push({
        image: faker.image.avatar(),
        name: faker.name.firstName(),
        address: faker.address.streetAddress(),
        intro: faker.lorem.words()
      })
    }
  }

}

We are pushing the mock data using faker inside the dataList for 1000 times using for loop.

 

Why Optimize this list?

If you notice in the above code, we are dumping a list of 1000 employees at a single time on the page. This approach is having the following issues:

  • Load on the server to fetch  1000 rows from the database.
  • Wastage of network resources to transfer unnecessary data.
  • Application performance is adversely affected due to loads of memory usage at once.
  • Slow rendering of the list with limited resources.

All these flows in the current approach will be resolved we implement virtual scroll and infinite scroll on our current list.

 

Implement Infinite Scroll on the List in Ionic

By adding an infinite scroll on the list, we will resolve the first two flows we discussed in the last section.

To implement the Infinite Scroll on the Ionic page, we add the ion-infinite-scroll component.

<ion-infinite-scroll threshold="100px" (ionInfinite)="loadData($event)">
    <ion-infinite-scroll-content loadingSpinner="bubbles" loadingText="Loading more data...">
    </ion-infinite-scroll-content>
  </ion-infinite-scroll>

The (ionInfinite) method is called when the user reaches the bottom of the page. After reaching the bottom we will call the getEmployees() method to load the next batch of employees and append to the existing list.

Now the getEmployees() method will only load 20 items at once.

 

So after adding the ion-infinite-scroll compoenent the home.page.html file will look like this

<ion-content [fullscreen]="true" class="ion-padding">

  <ion-list>
    <ion-list-header>
      Employee List
    </ion-list-header>

    <ion-item *ngFor="let item of dataList">
      <ion-avatar slot="start">
        <img src="{{item.image}}">
      </ion-avatar>
      <ion-label>
        <h2>{{item.name}}</h2>
        <h3>{{item.address}}</h3>
        <p>{{item.intro}}</p>
      </ion-label>
    </ion-item>
  </ion-list>


  <ion-infinite-scroll threshold="100px" (ionInfinite)="loadData($event)">
    <ion-infinite-scroll-content loadingSpinner="bubbles" loadingText="Loading more data...">
    </ion-infinite-scroll-content>
  </ion-infinite-scroll>


</ion-content>

In the home.page.ts file, we will add the loadDate(event) method

loadData(event) {

    // Using settimeout to simulate api call 
    setTimeout(() => {

      // load more data
      this.getEmployees()

      //Hide Infinite List Loader on Complete
      event.target.complete();

      // App logic to determine if all data is loaded
      // and disable the infinite scroll
      if (this.dataList.length == 1000) {
        event.target.disabled = true;
      }
    }, 500);
  }

The event.target.complete() method is called after successfully loading the data to hide the loading spinner on the bottom of the page.

To disable the infinite component we can call event.target.disabled = true; when no data is left to load.

 

Implement Virtual Scroll in Ionic App

Now to optimize our list to the next level, we will implement the Virtual Scroll component by adding the ion-virtual-scroll in the template.

Update Home Template

<ion-content [fullscreen]="true" class="ion-padding">

  <ion-list>
    <ion-list-header>
      Employee List
    </ion-list-header>

    <ion-virtual-scroll [items]="dataList">

      <ion-item *virtualItem="let item">
        <ion-avatar slot="start">
          <img src="{{item.image}}">
        </ion-avatar>
        <ion-label>
          <h2>{{item.name}}</h2>
          <h3>{{item.address}}</h3>
          <p>{{item.intro}}</p>
        </ion-label>
      </ion-item>

    </ion-virtual-scroll>

  </ion-list>


  <ion-infinite-scroll threshold="100px" (ionInfinite)="loadData($event)">
    <ion-infinite-scroll-content loadingSpinner="bubbles" loadingText="Loading more data...">
    </ion-infinite-scroll-content>
  </ion-infinite-scroll>


</ion-content>

We need to wrap the ion-item inside the ion-virtual-scroll with [items]="dataList" property. Then add the *virtualItem="let item" on ion-item which will replace the *ngFor directive we had earlier.

Update Home Class

One more thing need to be done. Open the home.page.ts file then add this.virtualScroll.checkEnd(); inside the loadDate() method to render the list after loading the data.

So the final code will look like this

// home.page.ts
import { Component, ViewChild } from '@angular/core';
import * as faker from 'faker';

import { IonInfiniteScroll, IonVirtualScroll } from '@ionic/angular';

@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage {

  dataList = [];

  @ViewChild(IonInfiniteScroll) infiniteScroll: IonInfiniteScroll;
  @ViewChild(IonVirtualScroll) virtualScroll: IonVirtualScroll;

  constructor() {
    this.getEmployees()
  }

  getEmployees() {
    for (let i = 0; i < 20; i++) {
      this.dataList.push({
        image: faker.image.avatar(),
        name: faker.name.firstName(),
        address: faker.address.streetAddress(),
        intro: faker.lorem.words()
      })
    }
  }

  loadData(event) {

    // Using settimeout to simulate api call 
    setTimeout(() => {

      // load more data
      this.getEmployees()

      //Hide Infinite List Loader on Complete
      event.target.complete();

      //Rerender Virtual Scroll List After Adding New Data
      this.virtualScroll.checkEnd();

      // App logic to determine if all data is loaded
      // and disable the infinite scroll
      if (this.dataList.length == 1000) {
        event.target.disabled = true;
      }
    }, 500);
  }

  toggleInfiniteScroll() {
    this.infiniteScroll.disabled = !this.infiniteScroll.disabled;
  }

}

 

That’s it. Run the application by hitting $ ionic serve --lab or $ ionic serve --open command.

 ionic-virtual-infinite-scroll-demo

You will notice in the image above that only a few rows are rendered in the DOM, if we scroll to load more items using Infinite Scroll components then previous rows get replaces by new ones keeping the DOM size the same.

Source Code

Fine source code in GitHub repository here.

 

Conclusion

In this tutorial, we learn how to implement Virtual Scroll and Infinite scroll together on a list of items. We used a faker to create dummy data to load in the ion-list component. We can user Grids, Cards table rows to render using the same method.

Hope you enjoyed this tutorial, do share your feedback …

 

 

Subscribe
Notify of
guest
2 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments
Yohan

Thanks for the walktrough.
Just note you should use <ion-img> and definitely not <img> for even more performance. It will prevent the load of images that you scroll really fast instead of loading them directly when added to the dom

Asura

I have done this but ion-inscroll not fired