H&H Soft Cloud
KLYRA The AI Lioness
Implementation

9 Governor-Limit-Friendly LWC Performance Patterns

Slow LWC components kill user adoption. These 9 patterns — lazy loading, wire caching, pagination, debouncing, and more — keep your Salesforce pages sub-second.

KI
Karthik Iyer
Senior LWC & Apex Engineer
Strategy Framework Discover Architect Build & Launch 🎯

Why LWC performance matters

Salesforce users tolerate 2-second page loads; at 3 seconds, adoption drops 40%. Lightning Web Components are fast by design (no framework abstraction, compiled templates), but poor patterns still cause slow pages: too many SOQL queries in wire adapters, synchronous Apex calls blocking the UI, unpaginated list views loading 2000 records, and reactive properties triggering re-renders on every keystroke. These 9 patterns keep your LWC pages sub-second.

Pattern 1: Use @wire with client-side caching

The @wire decorator caches responses automatically. If two components on the same page wire the same Apex method, only one SOQL fires. Always use @wire over imperative calls for data that doesn't change within a session. For data that does change, use refreshApex() to invalidate the cache explicitly — never bypass @wire with imperative calls 'just to be safe.'

Pattern 2: Lazy-load related data

Don't load all related records upfront. Use a 'Load more' button or infinite scroll that fetches the next 20 records via an imperative Apex call with an offset. The initial page load should show 20 records in <500ms; subsequent loads can take 1-2 seconds because the user expects them.

Pattern 3: Debounce search inputs

If a search input triggers a SOQL query, debounce it by 300-500ms. Without debouncing, typing 'Salesforce' fires 10 queries (S, Sa, Sal...). With debouncing, only one query fires after the user stops typing. Use a simple setTimeout/clearTimeout pattern or the debounce utility.

Pattern 4: Paginate server-side, not client-side

Never load 2000 records and paginate client-side — the initial load will take 10+ seconds and hit SOQL row limits. Instead, use SOQL OFFSET and LIMIT for server-side pagination. For large datasets (>1000 records), use SOQL query cursors (Database.getQueryLocator) which are more efficient than OFFSET.

Pattern 5: Minimize reactive properties

Every reactive property (@track or @api) triggers a re-render when it changes. If a form has 20 fields and each is reactive, typing in one field re-renders the entire form. Use a single reactive object and update it immutably, or use getters for derived values instead of storing them as separate reactive properties.

Pattern 6: Use LDS over Apex for record data

Lightning Data Service (LDS) via lightning-record-form, lightning-record-edit-form, or getRecord is cached, shared across components, and handles CRUD without Apex. It's 3-5x faster than a custom Apex call for the same record. Use Apex only for complex queries (joins, aggregates, external objects).

Pattern 7: Batch Apex for bulk operations

If a user action triggers >200 record updates, don't do it synchronously — use Batch Apex. The UI shows a toast ('Processing...') and the batch runs asynchronously. The user isn't blocked, and governor limits are respected (batches process 200 records per transaction).

Pattern 8: Avoid synchronous Apex in connectedCallback

connectedCallback runs before the component renders. If it calls Apex imperatively (without await), the component renders before data arrives — causing a flash of empty content. Use @wire for initial data, or use await in a connectedCallback async function with a loading spinner.

Pattern 9: Use CustomEvent for parent-child communication

Don't use a shared PubSub library for parent-child communication — use CustomEvent dispatch. It's synchronous, type-safe, and doesn't require a message channel. For sibling-to-sibling or cross-DOM communication, use Lightning Message Service (LMS) — but only when necessary.

"Salesforce users tolerate 2-second page loads; at 3 seconds, adoption drops 40%."

Key Takeaway

Use @wire with caching, lazy-load related data, debounce search inputs, paginate server-side, minimize reactive properties, prefer LDS over Apex, batch bulk operations, avoid synchronous Apex in connectedCallback, and use CustomEvent for parent-child comms.

Share:
KI
Karthik Iyer
Senior LWC & Apex Engineer

Karthik Iyer is a certified Salesforce expert at H&H Soft Cloud with 9+ years of hands-on experience across Sales Cloud, Service Cloud, Einstein AI, and MuleSoft integrations. They've led 50+ implementations for enterprise and mid-market clients.

Want this implemented?

Talk to a certified H&H Soft Cloud architect. Free 30-min consultation — no slides, no sales pitch, just expertise.

Talk to us