Understanding lazy loading in LWC
Lazy loading in Lightning Web Components (LWC) is the practice of deferring the loading of resources—components, data, images, or third-party libraries—until they are actually needed. The goal is to improve initial page performance, reduce bundle size, and provide a faster, more responsive user experience on Salesforce pages.
Why use lazy loading?
Benefits include reduced initial load time, lower memory usage, fewer server/API calls at startup, and improved perceived performance for end users. It’s especially useful for heavy components, large datasets, third-party libraries, and images.
Common lazy-loading techniques in LWC
Below are practical patterns you can use in LWC projects.
1) Render components on demand (conditional rendering)
Use conditional templates to avoid creating a heavy child component until needed (for example, on tab activation or user click).
// parentComponent.html
// parentComponent.js
import { LightningElement, track } from 'lwc';
export default class ParentComponent extends LightningElement {
@track showChild = false;
data = null;
handleShow() {
this.showChild = true; // child element is created only now
}
}
2) Lazy-load data using IntersectionObserver (load when visible)
Use IntersectionObserver to fetch data when a placeholder or anchor enters the viewport. This is useful for content below the fold or in long lists.
// lazyLoader.html
// lazyLoader.js
import { LightningElement, track } from 'lwc';
import getItems from '@salesforce/apex/MyController.getItems';
export default class LazyLoader extends LightningElement {
@track loaded = false;
@track items = [];
observer;
connectedCallback() {
// can also initialize observer in renderedCallback with a guard
}
renderedCallback() {
if (this.observer) {
return;
}
const options = { root: null, rootMargin: '0px', threshold: 0.1 };
this.observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting && !this.loaded) {
this.loaded = true;
this._loadData();
this.observer.disconnect();
}
});
}, options);
const anchor = this.template.querySelector('.anchor');
if (anchor) {
this.observer.observe(anchor);
}
}
async _loadData() {
try {
this.items = await getItems();
} catch (error) {
// handle error
}
}
}
3) Lazy-load third-party libraries and static resources
Use lightning/platformResourceLoader’s loadScript and loadStyle to load resources only when needed (e.g., when a chart or editor is shown).
import { loadScript, loadStyle } from 'lightning/platformResourceLoader';
import LIB from '@salesforce/resourceUrl/myLib';
connectedCallback() {
// Defer loading until user opens the widget
}
async loadLibIfNeeded() {
if (!this.libLoaded) {
try {
await loadScript(this, LIB + '/lib.min.js');
await loadStyle(this, LIB + '/lib.css');
this.libLoaded = true;
// initialize library
} catch (error) {
// handle
}
}
}
4) Lazy-load images
Use native browser lazy loading (loading="lazy") for images, or switch the src only when in view using IntersectionObserver to save bandwidth.
<img src="/path/to/image.jpg" loading="lazy" alt="..." />
5) Lazy-load on tab/change events or lightning-tabset
Delay data loading until tabs are activated (listen to tab activation events) to avoid fetching everything at once.
Best practices and caveats
- Prefer data-first lazy loading: avoid rendering heavy DOM until data is available.
- Use IntersectionObserver instead of scroll listeners for better performance and lower CPU usage.
- Keep accessibility in mind — ensure screen readers can still access content or provide fallback actions.
- When lazy-loading scripts, account for race conditions; show loading UI and fail gracefully.
- Test across browsers and Salesforce mobile app — IntersectionObserver is well supported but validate your target audiences.
- Avoid over-lazy-loading small, critical pieces — measure and prioritize the biggest wins first.
Summary
Lazy loading in LWC is about deferring work—component instantiation, data fetches, and resource loads—until they are required. Use conditional templates, IntersectionObserver, loadScript/loadStyle, tab-based triggers, and native browser features like loading="lazy" for images to dramatically improve initial load performance and user experience in Salesforce apps.








Leave a Reply