Search
  • Seiji Ralph Villafranca

Rendering Large Lists in Angular

In this tutorial, we will learn how to render large lists of data in Angular, I will demonstrate two ways how we can render lists in angular faster and more efficient.


So why did i write this tutorial ? We all know that Angular is a fast framework and it really improves the performance of our applications as it is a single page framework. Web components are loaded separately from the data to the client and the communication from the server is lessen as all components are already loaded in the client side but there are still instances that our Angular app can freeze and one instance is loading a huge amount of data in our components.


If you're familiar on how to iterate items in a component, we always see this code in our Angular app

<div *ngFor="let data of cars">
    <span>{{data.model}}</span>
    <span>{{data.color}}</span>
    <span>{{data.year}}</span>
</div>

the *ngFor directive is very common in Angular application as it is used to display array items on our view but as our array gets bigger and bigger, this will not be effective as it will iterate all our data and will try to display in our component, this will be very slow and will cause our browser to freeze.


1. Virtual Scrolling (Angular CDK)

The first strategy we can use to render large lists is Virtual Scrolling, we will achieve this using Angular CDK library by Material, this is the easiest to implement such that this is already provided as this will just be a directive that will be added in our component.


Our first step is to install the angular cdk in our application as a dependency.

npm i @angular/cdk

Next is we need to import the ScrollingModule from @angular/cdk/scrolling

import { ScrollingModule } from '@angular/cdk/scrolling';
@NgModule({
   imports: [ ScrollingModule, ...]
 })
export class AppModule {}  

And lastly, we can use the *cdkVirtualFor to replace our *ngFor directive and we will place the container inside the <cdk-virtual-scroll-viewport


<cdk-virtual-scroll-viewport itemSize="10">       
     <div *cdkVirtualFor="let data of cars">
        <span>{{data.model}}</span>     
        <span>{{data.color}}</span>     
        <span>{{data.year}}</span>
     </div>
</cdk-virtual-scroll-viewport>

The behavior of the iteration will now load the items that are only visible to the container, this will maintain the number of elements in the DOM and will prevent the slowing down of the page.


The Disadvantage of Angular CDK.

well, it is easy to integrate it in our part but it is a library, it is complex to modify the behavior of the virtual scrolling. Another downside is if we have a search feature, items that are not rendered will not be searchable.


2. Manual Rendering

The next strategy for iterating items is manual rendering, we will create the embedded view of each item using angular ng-container and ng-template.


suppose we have a simple iteration in our component.


<div *ngFor="let data of cars">
      <span>{{data.model}}</span>    
       <span>{{data.color}}</span>     
       <span>{{data.year}}</span>
  </div>
 

we can separate the content of each data into an ng-template

<div>
   <ng-container #carsContainer></ng-container>
<div>
<ng-template #item let-data="data">
   <span>{{data.model}}</span>     
   <span>{{data.color}}</span>     
   <span>{{data.year}}</span>
</ng-template>

and will render the items in our container base on the number of data in our array.

ViewContainerRef;
@ViewChild('item', { read: TemplateRef }) template: TemplateRef<any>
cars = *Array of cars*
private renderItem() {
      const end = this.cars.length;
      for (let n = 0; n < end; n++) {
        this.carsContainer.createEmbeddedView(this.template, {
          cars: cars[n]
        });
      }
  };

the renderItem() function will iterate the array of cars and will create a view of the template with data for each car, instead of using the *ngFor directive, we have rendered our view manually using template reference.


Bonus Strategy: Using trackBy

this next strategy is not necessarily for rendering large list in angular, but mainly it can improve the performance of our angular app when it comes to manipulating the list in our DOM, for example we add or delete an item in our list.


So how does trackBy improves the performance of our *ngFor directive? for example, we have an item of cars and we added a new item in our array, our angular App has no capability to identify which item has been added in the list having that it will re render all the elements again in our DOM, this will degrade the performance of the app as it will cause a large number of DOM manipulations, Adding the trackBy function will help Angular identify what items are added, modified or deleted by using a unique identifier of the data.


given with this code snippet.

<ul>      
  <li *ngFor="let data of cars ;trackBy: trackByFn">{{item.id}}</li>    </ul>

we simply apply the trackyBy in our ngFor and we will associate it with a function that will return the unique identifier or the index.


export class App{
   constructor(){
      this.cars=[{id: 1, brand: 'BMW'},{id: 2, brand: 'Dodge'}];
    }
      
   trackByFn(index, item){
     return index;/ / or item.id
   }
}

the trackByFn() will return the index of the item in the iteration, we can also use a unique identifer (id in this example) for the trackBy.


These are just some of the effective ways we can render our large lists in Angular, some strategies also include Pagination and Progressive rendering, this depends on the implementation and what your application requires.


Thank you for reading my tutorial and I hope you've learned a lot.

0 views

Follow me

© 2019 Seiji Villafranca
 

Call

0917-1368007

  • Facebook Clean
  • White LinkedIn Icon