Lazy loading in Lightning Web Component

In this post we will talk about How to implement Infinity or lazy loading in Lightning Web Component using Lightning Datatable. Lazy loading helps you to load the data only when it is required. Infinite scrolling (enable-infinite-loading) enables you to load a subset of data and then load more data when users scroll to the end of the table.

What is lazy loading?

Lazy loading is an optimization technique to load the content on-demand. Instead of loading the entire data and rendering it to the user in one go as in bulk loading, the concept of lazy loading assists in loading only the required section and delays the remaining, until it is needed by the user

Lazy loading in Lightning Web Component

In this post we will learn about lightning datatable attributes enable-infinite-loading and load more offset.

  1. enable-infinite-loading : You can load a subset of data and then display more
    when users scroll to the end of the table. Use with the onloadmore event handler to retrieve more data
  2. load-more-offset : Determines when to trigger infinite loading based on how many pixels the table’s scroll position is from the bottom of the table. The default is 20
  3.  onloadmore : The action triggered when infinite loading loads more data

In below image you can check the demo for Lightning Data Table With Lazy Loading. As we load data partially and once the user scrolls down at the end then we load the next set of data. So it is very responsive.

Lets see how we can implement the same.

Step 1) Apex Class with offSet

LazyLoadingController

public with sharing class LazyLoadingController {

    @AuraEnabled(cacheable=true)
    public static List<Account> getAccounts(Integer limitSize, Integer offset){
        List<Account> accountList = [SELECT Id,Name,Rating
                                     FROM Account
                                     ORDER BY CreatedDate
                                     LIMIT :limitSize
                                     OFFSET :offset
                                     ];
        return accountList;
    }
}

We will call same apex class from lightning web component.

Step 2) Lightning web component with Datatable

Create lightning web component in your sandbox or developer org

lazyLoadingLWCDemo.html

<template>
    <div style="height:500px">
    <lightning-datatable key-field="Id"
            data={accounts}
            columns={columns}
            enable-infinite-loading
            onloadmore={loadMoreData}
            hide-checkbox-column="true"
            show-row-number-column="true">
    </lightning-datatable> 
</div>
</template>

To enable infinite scrolling, specify enable-infinite-loading and provide an event handler using onloadmore.

lazyLoadingLWCDemo.js

import { LightningElement, track, wire } from 'lwc';
import getAccounts from '@salesforce/apex/LazyLoadingController.getAccounts';

const columns = [
    { label: 'Id', fieldName: 'Id', type: 'text' },
    { label: 'Name', fieldName: 'Name', type: 'text'},
    { label: 'Rating', fieldName: 'Rating', type: 'text'}
  
];

export default class LazyLoadingLWCDemo extends LightningElement {
    accounts=[];
    error;
    columns = columns;
    rowLimit =25;
    rowOffSet=0;
  
    connectedCallback() {
        this.loadData();
    }

    loadData(){
        return  getAccounts({ limitSize: this.rowLimit , offset : this.rowOffSet })
        .then(result => {
            let updatedRecords = [...this.accounts, ...result];
            this.accounts = updatedRecords;
            this.error = undefined;
        })
        .catch(error => {
            this.error = error;
            this.accounts = undefined;
        });
    }

    loadMoreData(event) {
        const currentRecord = this.accounts;
        const { target } = event;
        target.isLoading = true;

        this.rowOffSet = this.rowOffSet + this.rowLimit;
        this.loadData()
            .then(()=> {
                target.isLoading = false;
            });   
    }


}

We create connectedCallback function to load the initial data and then we are useing loadmoreData function to load more record from Apex base on offset. The onloadmore event handler retrieves more data when you scroll to the bottom of the table until there are no more data to load. To display a spinner while data is being loaded, set the isLoading property to true

lazyLoadingLWCDemo.js-meta.xml

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>48.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__HomePage</target>
    </targets>  
</LightningComponentBundle>

Please share your feedback and let me know if this code can be improve.

Amit Chaudhary
Amit Chaudhary

Amit Chaudhary is Salesforce Application & System Architect and working on Salesforce Platform since 2010. He is Salesforce MVP since 2017 and have 17 Salesforce Certificates.

He is a active blogger and founder of Apex Hours.

Articles: 473

6 Comments

  1. What is the currentRecord assignment in loadMoreData for? That variable isn’t used anywhere after that assignment.
    Also, would this.accounts.push(…result) be more efficient than using another variable and two statements? (Honest question, I don’t know JS well enough to know.)

  2. How can we implement this lazy loading when we have custom tables instead of standard data tables in lwc
    Please share code.

  3. I want to lazy loading functionality on large data like 1L records. But Offset only works up to 2K records.

    Error : NUMBER_OUTSIDE_VALID_RANGE: Maximum SOQL offset allowed for apiName Account is 2000

    • @Ranjeet, instead of using OFFSET, you can implement lazy loading with an ID filter to handle large datasets.

      For Example:
      ——————-
      SELECT Id, Name, CreatedDate FROM Account WHERE Id > :lastAccountId ORDER BY Id LIMIT 100

      This query retrieves the next 100 records after the specified `lastAccountId`. Just pass the last account ID to apex from LWC.

      Thanks,
      Pritam H

Leave a Reply

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