Optimizing Salesforce lightning web components for performance and scalability
2024-07-29 15:54
This article is prepared by our Salesforce Developer Palina Skvartsova.
Salesforce Lightning Web Components (LWCs) provide a modern framework for building responsive, efficient web applications on the Salesforce platform. However, to fully leverage the power of LWCs, developers must adopt best practices for optimizing performance and scalability. In this article, we will explore key strategies and techniques for enhancing the efficiency and robustness of your Lightning Web Components. From efficient data handling and lazy loading to event handling and rendering optimization, we will cover a range of methods to help you build scalable, high-performing Salesforce applications.
Tips for LWC Performance Optimization
Efficient Data Handling
Client-side data caching improves performance by allowing components to share data, significantly decreasing the number of calls to the server. LWC has two built-in mechanisms for caching:
Lightning Data Service offers a managed record approach, eliminating the need for you to write data access logic, which means no Apex code is required. It also ensures security by verifying the accessibility of records and fields. The framework handles record management, including initially fetching records from the server, storing them in a highly efficient client-side cache, sharing them among all components that request them, and updating the server and cache when related Salesforce data changes.
Cacheable Apex method is a server action whose response is stored in the client cache. This allows subsequent requests for the same method with identical arguments to be retrieved from the cache rather than making a server call.
Just annotate a method with @AuraEnabled(cacheable=true) to make it cacheable.
Also, keep the following in mind when working with data in LWC:
Before making server calls, try to find another data retrieval option. Opt for passing data between components using attributes, events, or methods where applicable, rather than redundantly retrieving data in different components. For scenarios where multiple components require the same data on a page, consider creating a service component that has no UI elements. This service component can efficiently query data once and distribute it to other components as needed.
Limit the fields and rows that you want to query in Apex controller. For example: only select the fields you need, set a LIMIT on the query, implement pagination when queries may have large results sets.
It's preferable to handle data sorting or data modification in the JavaScript controller rather than in the Apex controller. This approach reduces server requests, improves application responsiveness, and leverages client-side processing for efficient data manipulation, enhancing overall user experience and performance.
Component Design
Lazy Loading is telling us that the component should load the content on-demand. So lazy loading improves efficiency by loading only the necessary data initially and deferring the rest until the user needs it.
Let's look at this using a lightning datatable as an example. We can use one of three options (enable-infinite-loading, load-more-offset or onloadmore) to load data partially and once the user scrolls down at the end then we load the next set of data.
Component Composition. Break down complex components into smaller, reusable components.
Conditional Rendering. You can conditionally render DOM elements using if:true|false to lazily instantiate parts of the UI.
Event Handling
Lightning web components dispatch standard DOM events and can also create custom events. These events facilitate communication up the component hierarchy. Keep in mind following when designing events to ensure scalability and maintainability of your LWC applications:
Limit event handlers to only those that are absolutely necessary. Each handler adds overhead, and having too many can degrade your app's performance.
Ensure you understand the event propagation mechanism between parent and child components, specifically the use of bubbles and composed properties.
You can use Lightning Message Service to facilitate communication between sibling components within a single Lightning page or across multiple pages. It offers the flexibility of working seamlessly across Visualforce, Aura, LWC, utility bar components, and page tabs in a console application.
When adding a listener to elements outside of the component lifecycle (such as the window or document objects), it's your responsibility to remove the listener manually. Use the removeEventListener() method within the disconnectedCallback lifecycle hook. Neglecting to do this can lead to memory leaks, gradually impacting the performance of the entire Lightning app until the user closes or refreshes their browser tab.
Rendering Optimization
Avoid Re-rendering. Lightning web components have a lifecycle controlled by the framework. The framework handles component creation, insertion into the DOM, rendering, and removal from the DOM. Familiarize yourself with the rendering lifecycle to grasp its stages and the methods triggered at each phase. Minimize reactivity to avoid unnecessary component re-renders.
Track Reactive Properties. Use @track wisely to limit reactive properties to those that are necessary.
Image Optimization
Whenever possible, opt for SLDS icons (utilizing <lightning-icon> and <lightning-button-icon>) over custom icons. Salesforce provides hundreds of icons, allowing you to reuse existing ones rather than investing time in creating custom ones. When choosing other images, ensure you lock image dimensions to prevent reflows and serve the image in those specific dimensions whenever possible.
By implementing these strategies, you can significantly improve the performance of Lightning Web Components in Salesforce.