lwc-performance

Use when designing or reviewing Lightning Web Components for slow initial load, heavy rerenders, large-list rendering, payload reduction, and lazy instantiation choices such as `lwc:if`, tabs, or dynamic components. Triggers: 'slow lwc', 'rerenders too much', 'key index', 'dynamic import', 'large list lag'. NOT for wire-service data-source selection when provisioning strategy is the only question or for mobile/offline-specific tuning.

Best use case

lwc-performance is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Use when designing or reviewing Lightning Web Components for slow initial load, heavy rerenders, large-list rendering, payload reduction, and lazy instantiation choices such as `lwc:if`, tabs, or dynamic components. Triggers: 'slow lwc', 'rerenders too much', 'key index', 'dynamic import', 'large list lag'. NOT for wire-service data-source selection when provisioning strategy is the only question or for mobile/offline-specific tuning.

Teams using lwc-performance should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/lwc-performance/SKILL.md --create-dirs "https://raw.githubusercontent.com/PranavNagrecha/AwesomeSalesforceSkills/main/skills/lwc/lwc-performance/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/lwc-performance/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How lwc-performance Compares

Feature / Agentlwc-performanceStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Use when designing or reviewing Lightning Web Components for slow initial load, heavy rerenders, large-list rendering, payload reduction, and lazy instantiation choices such as `lwc:if`, tabs, or dynamic components. Triggers: 'slow lwc', 'rerenders too much', 'key index', 'dynamic import', 'large list lag'. NOT for wire-service data-source selection when provisioning strategy is the only question or for mobile/offline-specific tuning.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# LWC Performance

Use this skill when the LWC works functionally but costs too much: slow first paint, laggy filters, expensive list rerenders, or optional UI that loads before the user asks for it. Optimize payload size, component instantiation, and DOM churn before reaching for micro-optimizations.

---

## Before Starting

Gather this context first:

- Is the pain on initial page load, after a user interaction, or only when the data set grows?
- Is the component using LDS base components, UI API wire adapters, the GraphQL wire adapter, or Apex, and how much data is being requested?
- Which UI sections are always needed, and which sections could be deferred behind tabs, disclosure, or conditional rendering?
- If dynamic components are being considered, is Lightning Web Security enabled and is the package model compatible with `lightning__dynamicComponent`?

---

## Core Concepts

Performance problems in LWC usually come from one of four places: too much data, too many component instances, unstable list identity, or reactivity that causes more rerendering than the user actually needs.

### Start With The Cheapest Data Path

Salesforce’s own guidance is to prefer base components built on Lightning Data Service, then LDS/UI API wire adapters, then GraphQL for multi-entity reads, and Apex only when those options do not fit. That order matters for performance because LDS shares cache, security checks, and refresh behavior across components. It is also why layout-based record fetches are a red flag for narrow UIs: you often pay for hundreds of fields when the component needs five.

### Reactivity Controls Rerender Cost

Primitive fields rerender when their value identity changes. Objects and arrays rerender when you assign a new value, and `@track` is only the deep-observation tool for plain objects and arrays. It does not make `Date`, `Set`, or `Map` mutations observable. Another important nuance from the docs: even with `@track`, LWC rerenders only when properties accessed during the previous render change. That is good for performance, but it surprises teams that mutate an object in place and expect broad UI refreshes.

### Template Directives Affect Instantiation And Evaluation

`lwc:if`, `lwc:elseif`, and `lwc:else` are the current conditional-rendering primitives. Salesforce explicitly says `if:true` and `if:false` are no longer recommended, may be removed in the future, and are less performant in chained conditions. Use getters for computed conditions and treat conditional rendering as a performance tool: if a section is not needed yet, avoid instantiating it yet.

### Lists Need Stable Identity And Bounded Size

When a list changes, the framework uses `key` to rerender only the affected items. The key must be stable, unique, and not the loop index. Stable keys reduce DOM churn; bounded list size reduces the absolute amount of DOM to diff. For large datasets, paginate, virtualize, or progressively reveal more rows rather than rendering every record at once.

### Dynamic Import Is Specialized, Not The Default

Dynamic components can help avoid loading large modules that are not always needed, but Salesforce’s current documentation is explicit about the tradeoff: dynamic import adds runtime overhead, requires Lightning Web Security, and dynamic components are supported only in managed packages, not unlocked packages. Start with static imports. Move to dynamic import only when the deferred component is genuinely heavy or unknown until runtime.

---

## Common Patterns

These patterns solve most real LWC performance issues without adding brittle complexity.

### Data-Minimized Read Model

**When to use:** The UI reads Salesforce data and feels slow because it requests full layouts, multiple overlapping calls, or Apex for standard CRUD-shaped reads.

**How it works:** Prefer LDS base components for standard record UI, LDS/UI API wire adapters for focused reads, and the GraphQL wire adapter when one query can replace multiple requests. Request only the fields and rows you need. If Apex remains necessary, make the caching and refresh behavior explicit.

**Why not the alternative:** Layout-based fetches and generic Apex wrappers often inflate payload size, bypass shared cache advantages, and create unnecessary refresh work.

### Progressive Disclosure And Lazy Instantiation

**When to use:** The component contains analytics panels, secondary tabs, modals, or rarely used renderers that do not need to exist on first paint.

**How it works:** Use `lwc:if`, App Builder visibility, or lazy tab/content patterns so the expensive child component is created only when the user asks for it. Use dynamic components only when the constructor is optional at runtime and the package and LWS constraints are satisfied.

**Why not the alternative:** Rendering every optional child up front increases bundle cost, component creation time, and server work before the user has expressed intent.

### Bounded Lists With Stable Keys

**When to use:** Search results, dashboards, or custom data tables render dozens or hundreds of repeated child rows.

**How it works:** Page or virtualize the collection, use a unique key from the incoming dataset, and prefer event delegation on the list container instead of one listener per row.

**Why not the alternative:** `key={index}` and unlimited list rendering cause row identity bugs, listener bloat, and full-list rerender churn when only one row changed.

## Decision Guidance

| Situation | Recommended Approach | Reason |
|---|---|---|
| Standard record view or edit UI | Use LDS base components first | Built-in caching and security with less custom code |
| Component needs a narrow read model | Use UI API or GraphQL and request exact fields | Smaller payload and fewer calls |
| Optional heavy panel or tab | Gate it with `lwc:if` or lazy tab activation | Avoid up-front instantiation cost |
| Renderer is chosen from metadata at runtime in a managed package | Use dynamic components with a statically analyzable import map | Deferred loading is justified and platform constraints are met |
| Large result set or custom table | Paginate or virtualize and use stable row keys | Reduces DOM size and preserves row identity |

---


## Recommended Workflow

Step-by-step instructions for an AI agent or practitioner activating this skill:

1. Gather context — confirm the org edition, relevant objects, and current configuration state
2. Review official sources — check the references in this skill's well-architected.md before making changes
3. Implement or advise — apply the patterns from Core Concepts and Common Patterns sections above
4. Validate — run the skill's checker script and verify against the Review Checklist below
5. Document — record any deviations from standard patterns and update the template if needed

---

## Review Checklist

Run through these before marking work in this area complete:

- [ ] The component uses the cheapest viable data path before custom Apex is introduced.
- [ ] Record reads request explicit fields instead of layout-based payloads.
- [ ] Nonessential panels, tabs, or child components are deferred intentionally.
- [ ] Lists use stable non-index keys and do not render an unbounded number of rows.
- [ ] Conditional rendering uses `lwc:if` chains instead of legacy `if:true` or `if:false`.
- [ ] Object and array state updates rely on reassignment or intentional `@track` usage.
- [ ] Any dynamic import has a clear benefit and satisfies LWS plus managed-package constraints.

---

## Salesforce-Specific Gotchas

Non-obvious platform behaviors that cause real production problems:

1. **`if:true` and `if:false` still work, but they are the slower legacy path** — Salesforce now recommends `lwc:if` and notes that chained `if:true` or `if:false` checks are not as performant and may be removed in the future.
2. **`@track` is not a general deep-reactivity switch** — it observes plain objects and arrays, but not internal mutations to `Date`, `Set`, `Map`, or class instances.
3. **The list key is part of the rendering contract** — missing keys or `key={index}` force more DOM churn and can scramble row-specific UI state.
4. **Dynamic components are not a universal lazy-loading trick** — they require LWS, `lightning__dynamicComponent`, and managed-package support, and they are not prefetched automatically.
5. **Layout-shaped record fetches are expensive by default** — a simple card can become slow because the payload includes far more data than the UI renders.

---

## Output Artifacts

| Artifact | Description |
|---|---|
| Performance review | Prioritized findings on payload size, rerendering, list scale, and deferred UI opportunities |
| Refactor plan | Concrete steps to reduce data, delay instantiation, or stabilize list rendering |
| Checker report | File-level findings for deprecated directives, list keys, layout fetches, and dynamic-component setup |

---

## Related Skills

- `lwc/wire-service-patterns` — use when the core decision is which data provisioning model to choose rather than UI rendering cost.
- `lwc/lifecycle-hooks` — use when the main problem is `renderedCallback`, listener cleanup, or lifecycle-driven rerender bugs.
- `lwc/lwc-offline-and-mobile` — use when the performance issue is specific to mobile containers, connectivity, or device constraints.

Related Skills

omnistudio-performance

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when diagnosing or improving runtime performance in OmniStudio assets: slow OmniScripts, Integration Procedures with high latency, DataRaptor caching, excessive API call counts, FlexCard rendering delays, or async IP fire-and-forget patterns. Triggers: 'OmniScript slow', 'Integration Procedure timeout', 'DataRaptor cache', 'FlexCard loading too long', 'reduce API calls OmniStudio'. NOT for LWC performance outside of OmniScript runtime (use lwc-performance skill). NOT for OmniScript step design or journey UX (use omniscript-design-patterns skill).

lwc-performance-budgets

8
from PranavNagrecha/AwesomeSalesforceSkills

Set and enforce performance budgets for Lightning Web Components: bundle-size limits per component, LCP/INP field targets, wire-adapter count caps, and CI-gate configuration using Lighthouse or webpagetest. Trigger keywords: lwc performance budget, bundle size limit, lcp budget, lighthouse ci, lwc size gate. Does NOT cover runtime optimization techniques, Lightning page tuning, or general LCP causes (see lwc-performance).

flow-performance-optimization

8
from PranavNagrecha/AwesomeSalesforceSkills

Tune Flow runtime performance: pick Before-Save over After-Save, consolidate Get Records, eliminate loop-DML, cache lookups, split with Scheduled Paths, and measure actual runtime. Covers benchmarking methodology, profiling tools, and the 80/20 wins. NOT for governor-limit math (use flow-governor-limits-deep-dive). NOT for LDV strategy (use flow-large-data-volume-patterns).

performance-testing-salesforce

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when planning or executing load tests, stress tests, or performance benchmarks against a Salesforce org. Covers Salesforce Scale Test, third-party tools (JMeter, BlazeMeter, k6), API throughput testing, Experience Page Time (EPT) measurement, and sandbox sizing for performance work. Triggers: 'load test Salesforce org', 'Scale Test Full Copy sandbox', 'EPT optimization', 'API concurrency limits', 'JMeter Salesforce performance'. NOT for Apex unit test performance assertions, LWC Jest tests, query optimization (see data/soql-query-optimization), or NFR definition (see architect/nfr-definition-for-salesforce).

sharing-recalculation-performance

8
from PranavNagrecha/AwesomeSalesforceSkills

Plan, batch, and monitor Salesforce sharing recalculation jobs — including OWD changes, sharing rule add/remove, role hierarchy restructuring, and Apex managed share rebuild — to avoid multi-hour background jobs and data-access blackouts. NOT for diagnosing data-skew root causes (use admin/data-skew-and-sharing-performance), NOT for designing the sharing model itself (use admin/sharing-and-visibility), and NOT for Apex managed sharing row-cause creation (use apex/apex-managed-sharing).

cpq-performance-optimization

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when diagnosing or resolving slow CPQ quote calculation, QLEx timeouts, or governor limit errors on large quotes. Trigger keywords: Large Quote Mode, QCP field declaration, quote calculation performance, SBQQ calculation timeout, async pricing. NOT for generic Apex performance tuning, CPQ pricing rule logic design, or billing engine performance.

experience-cloud-performance

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when diagnosing slow Experience Cloud site load times, planning CDN and caching strategy, optimizing page weight, or advising on component loading patterns for Aura and LWR-based sites. Trigger phrases: 'Experience Cloud site loads slowly', 'CDN cache not updating after publish', 'LWR site stale after deployment', 'too many Apex calls on Experience Cloud page', 'browser caching Experience Builder', 'CDN configuration Experience Cloud', 'how to reduce page load time community site', 'Experience Cloud performance audit'. NOT for LWC component-level JavaScript performance (use lwc/lwc-performance). NOT for initial site setup (use admin/experience-cloud-site-setup). NOT for multi-site topology decisions (use architect/multi-site-architecture).

formula-field-performance-and-limits

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when diagnosing SOQL performance problems caused by formula fields, hitting formula compile-size limits, or deciding whether to replace a formula field with a stored field for indexing. Triggers: 'formula field slowing SOQL', 'compile size limit', 'cross-object formula spanning limit', 'formula field not indexable', 'LDV query full table scan', 'SOQL WHERE on formula'. NOT for formula syntax help, building formula expressions, or authoring new formulas from scratch — use admin/formula-fields for that.

cross-object-formula-and-rollup-performance

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when diagnosing or preventing performance problems caused by cross-object formula spanning relationships and roll-up summary field recalculations — especially in LDV orgs. Triggers: 'roll-up summary timing stale in trigger', 'Maximum 15 object references error', 'rollup recalculation timeout on large child set'. NOT for formula syntax authoring (use admin/formula-fields), formula compile-size limits (use apex/formula-field-performance-and-limits), or general governor-limit troubleshooting.

apex-performance-profiling

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when diagnosing where Apex transactions spend CPU, heap, SOQL, or DML time using the Salesforce diagnostic toolchain: Apex Log Analyzer flame graphs in VS Code, Developer Console execution timeline, SOQL Query Plan tool, and Limits-class checkpoint instrumentation. Triggers: 'why is my Apex slow', 'flame graph Apex', 'profile Apex transaction', 'Query Plan tool', 'Apex Log Analyzer'. NOT for fixing specific CPU or heap patterns after the hotspot is found (use apex-cpu-and-heap-optimization), NOT for debug log setup or trace flag mechanics (use debug-logs-and-developer-console), and NOT for SOQL query rewriting (use soql-query-optimization).

report-performance-tuning

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when a report or dashboard is slow, timing out, hitting row limits, or consuming excessive system resources on large-volume objects — covers selective filter strategy, custom report type optimization, async report execution via Analytics API, dashboard refresh scheduling, and grouping/aggregation tuning. Triggers: 'report times out', 'report is slow', 'dashboard not refreshing', 'report row limit hit', 'too many report results'. NOT for CRM Analytics / Tableau CRM performance (separate skill). NOT for sharing-model or visibility issues causing missing rows (use admin/sharing-and-visibility). NOT for building or designing reports from scratch (use admin/reports-and-dashboards-fundamentals).

lightning-page-performance-tuning

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when a Lightning record page, home page, or app page is slow to load or render — covers Experienced Page Time (EPT) analysis, component count reduction, progressive disclosure via tabs and conditional rendering, Lightning Experience Insights diagnostics, and DOM/XHR minimization strategies. Triggers: 'Lightning page is slow', 'EPT is high', 'record page takes too long to load', 'too many components on page', 'Lightning Experience Insights shows slow page', 'how to optimize Lightning page performance'. NOT for Visualforce page performance (separate concern). NOT for Apex or SOQL query optimization (use apex/apex-cpu-and-heap-optimization or data/soql-query-optimization). NOT for report or dashboard performance (use admin/report-performance-tuning).