Why LWC Performance Matters
Salesforce Lightning Web Components (LWC) are designed to be lightweight and fast—but poor development practices can quickly bloat components, slow down rendering, and frustrate users. Whether you’re building a dashboard, data-entry form, or mobile interface, performance optimization is key.
In this guide, you’ll find 15 advanced LWC tips to boost speed, maintain UX fluidity, and make your Salesforce apps shine—even at scale.
1. Use lwc:if
Over if:true={}
Why: It supports branching logic (if / elseif / else
) and simplifies conditional UI rendering.
2. Reduce Re-Renders Using Object Spread
Instead of updating properties one-by-one, use object spread syntax to batch updates and trigger only one re-render.
jsCopyEditthis.user = { ...this.user, name: 'Alex', age: 30 };
3. Debounce Inputs to Minimize Apex Load
Avoid triggering Apex for every keystroke. Use lodash.debounce
or custom functions.
4. Use @wire
with cacheable=true
Prefer @wire
over imperative calls for simple reads. This allows Salesforce to cache responses.
apexCopyEdit@AuraEnabled(cacheable=true) public static List<Account> getAccounts() { return [SELECT Id, Name FROM Account]; }
jsCopyEdit@wire(getAccounts) accounts;
5. Lazy Load Scripts with loadScript
Only load resources like Chart.js or Moment.js when necessary.
jsCopyEditimport { loadScript } from 'lightning/platformResourceLoader';
loadChartJs() {
if (!this.chartJsLoaded) {
loadScript(this, chartJs).then(() => {
this.chartJsLoaded = true;
this.initChart();
});
}
}
6. Flatten Deeply Nested Components
Avoid nesting 3+ levels deep. Prefer slots or modular flat components for reuse and performance.
7. Use Lightning Data Service (LDS) for Standard CRUD
htmlCopyEdit<lightning-record-form
object-api-name="Contact"
record-id={recordId}
layout-type="Compact"
mode="view"
></lightning-record-form>
8. Cache DOM Selectors and Avoid Loops
jsCopyEditconnectedCallback() {
this.searchInput = this.template.querySelector('.search-input');
}
Don’t call querySelector
inside loops or frequent callbacks.
9. Use requestAnimationFrame()
for DOM Animations
jsCopyEditrenderedCallback() {
window.requestAnimationFrame(() => {
this.renderChart();
});
}
This helps browser batching and smooth UI updates.
10. Avoid Heavy Logic in renderedCallback
jsCopyEditrenderedCallback() {
if (this.initialized) return;
this.initialized = true;
this.initializeData();
}
11. Use for:each
with key
for Lists
htmlCopyEdit<template for:each={contacts} for:item="contact">
<p key={contact.Id}>{contact.Name}</p>
</template>
12. Break Large Components into Small, Testable Units
Split dashboards, wizards, and tables into small subcomponents. This reduces rendering cost and increases testability.
13. Use Computed Getters for Conditional Logic
jsCopyEditget showChart() {
return this.hasData && !this.hasError;
}
htmlCopyEdit<template lwc:if={showChart}>
<c-performance-chart data={chartData}></c-performance-chart>
</template>
14. Use Chrome DevTools + LWC Inspector
- LWC Inspector: Analyze component hierarchy, reactivity, and wire performance.
- DevTools: Track memory, network latency, and DOM rendering time.
15. Watch Salesforce Governor Limits
Limit Type | Threshold | Optimization Tip |
---|---|---|
SOQL Queries | 100/query | Combine queries, use maps |
Heap Size | 6MB/12MB | Avoid massive JSON, large objects |
CPU Time | 10,000ms | Flatten loops, avoid nested calls |
DML Statements | 150/tx | Use upsert , bulk inserts |
✅ Final Developer Checklist
- All lists use
for:each
+key
lwc:if
used instead ofif:true
- DOM queries are cached
- Lazy loading via
loadScript
- Debounced input handling
- No heavy logic in lifecycle methods