How you optimize a react applicatio
Categories: initial load (code splitting, RSC, image pipeline, critical CSS), runtime renders (memo + stable refs, split context, virtualize, defer non-urgent updates), data layer (React Query for caching/dedup, optimistic UI), bundle hygiene (analyzer, tree shaking, dynamic imports), observability (web-vitals RUM, Sentry). Profile before optimizing. Structural fixes beat micro-memo.
Same territory as [[what-are-common-performance-bottlenecks-in-react-apps]] and [[how-do-you-debug-performance-issues-in-react]]. Here's the optimization playbook.
1. Measure first
RUM in production (web-vitals → analytics). Set p75 budgets: LCP < 2.5s, INP < 200ms, CLS < 0.1.
2. Initial load
- Per-route code splitting (Next.js does this; in Vite/React,
React.lazyper route). - Tree shaking — verify with bundle analyzer.
- Replace heavy deps — moment → date-fns, full lodash → per-import or just JS.
- Dynamic import heavy modals / charts / editors.
- Image pipeline — AVIF/WebP, responsive srcset,
<Image>(Next), lazy below the fold. - Critical CSS inlined; rest async.
- Self-host fonts;
font-display: swap+ preload. - Server Components (App Router) — ship less JS.
- Streaming SSR — flush above-the-fold first.
3. Runtime renders
- React.memo on genuinely expensive components with stable prop refs.
- useCallback/useMemo for refs passed to memo'd children or as effect deps.
- Split context when value changes often → fan-out cost.
- Move hot state out of Context to a selector store (Zustand).
- Virtualize lists > ~200 rows.
- useDeferredValue / startTransition for non-urgent updates.
4. Data layer
- React Query / SWR for server state — caching, dedup, background refetch.
- Optimistic UI for sends.
- Cancel stale requests with AbortController.
- Avoid waterfalls — parallel fetch when possible; RSC for server-side coordination.
5. Bundle hygiene
- Analyzer in CI; alert on regressions.
- Per-route chunks, vendor chunk for cache stability.
- modulepreload for module-graph deps.
- No CommonJS bloat in ESM bundle — check.
- Drop polyfills for modern browsers.
6. Interaction perf (INP)
- Break long tasks (chunk + yield, scheduler.yield, requestIdleCallback).
- Workers for heavy compute.
- Debounce hot handlers.
- Avoid layout thrash (batch reads/writes).
- Reduce hydration cost (RSC).
7. Memory
- Cleanup every subscription in useEffect return.
- AbortController for fetches.
- Bounded caches (LRU).
- Avoid leaky closures over big data.
8. CSS / DOM
contain: layout style painton isolated subtrees.- Composite-only animations (transform/opacity).
- Reduce DOM node count (virtualize, RSC).
- Avoid expensive selectors (heavy
:has).
9. Observability
- web-vitals → analytics.
- Sentry with performance + breadcrumbs.
- Long Tasks API in dev / staging.
- Bundle budget regression alerts.
Prioritization
Don't do all of this. Start with:
- RUM numbers.
- Worst metric (LCP, INP, CLS).
- Profile the offending route/interaction.
- Apply the targeted fix.
- Measure delta.
- Move to next.
Interview framing
"Structure by category: initial load (code splitting, RSC, image pipeline, critical CSS, self-hosted fonts), runtime renders (memo on hot paths with stable refs, split context, virtualize, transitions), data layer (React Query for server state, optimistic UI, cancellation), bundle hygiene (analyzer + budgets), INP (break long tasks, Workers, debounce), memory (cleanup, bounded caches). Always measure first — RUM in prod for actual user distribution, profile to find the actual hot path, apply structural fixes before micro-memo. The biggest wins are usually RSC + virtualization + image pipeline + caching, not sprinkling useMemo."
Follow-up questions
- •Walk through optimizing a specific app you worked on.
- •What's the single highest-leverage React perf change?
- •When are RSCs the right answer?
Common mistakes
- •Optimizing without measuring.
- •Micro-memo over structural fixes.
- •Ignoring INP and only optimizing for LCP.
Performance considerations
- •The whole topic.
Edge cases
- •Edge runtime trade-offs.
- •Workers across CSP boundaries.
- •Suspense fallback flickers.
Real-world examples
- •Vercel docs perf series, React Server Components blog, web.dev case studies.