← Back to Chapters

Performance Optimization

? Performance Optimization

⚡ Quick Overview

React provides powerful tools and patterns to build fast, responsive applications. As applications grow, performance can degrade due to unnecessary re-renders, large bundles, and inefficient rendering strategies.

? Key Concepts

  • Avoid unnecessary re-renders
  • Memoize expensive calculations
  • Optimize large lists
  • Use lazy loading and code splitting
  • Profile performance using React DevTools

? Syntax & Theory

React performance optimization focuses on minimizing render work, reducing bundle size, and efficiently managing state updates. Hooks like useMemo and useCallback help memoize values and functions.

? Avoid Unnecessary Re-renders

? View Code Example
// React.memo prevents re-render if props do not change
import React from "react";

const Button = React.memo(({ onClick, label }) => {
console.log("Rendered:", label);
return <button onClick={onClick}>{label}</button>;
});
? View Code Example
// useCallback memoizes event handlers
const handleClick = useCallback(() => {
console.log("Clicked!");
}, []);

? Memoize Expensive Calculations

? View Code Example
// useMemo caches expensive calculations
import React, { useMemo } from "react";

function PrimeCalculator({ limit }) {
const primes = useMemo(() => {
const result = [];
for (let i = 2; i <= limit; i++) {
if (result.every(p => i % p !== 0)) result.push(i);
}
return result;
}, [limit]);

return <p>Found {primes.length} primes</p>;
}

⚙️ Optimize Lists and Tables

? View Code Example
// react-window renders only visible list items
import { FixedSizeList as List } from "react-window";

function MyList({ items }) {
return (
<List height={300} itemCount={items.length} itemSize={35} width={300}>
{({ index, style }) => <div style={style}>{items[index]}</div>}
</List>
);
}

? Code Splitting & Lazy Loading

? View Code Example
// Lazy load components using React.lazy and Suspense
const Dashboard = React.lazy(() => import("./Dashboard"));

<Suspense fallback={<div>Loading...</div>}>
<Dashboard />
</Suspense>

? Minimize Bundle Size

  • Enable tree shaking
  • Split vendor libraries
  • Compress assets
  • Analyze bundles regularly

? Optimize Rendering & State

  • Avoid unnecessary global state
  • Use Context sparingly
  • Split components logically
  • Use fine-grained state libraries

? React Profiler

? View Code Example
// Measure render performance using React Profiler
<React.Profiler id="App" onRender={(id, phase, actualDuration) => {
console.log(`Rendered ${id} during ${phase} in ${actualDuration}ms`);
}}>
<App />
</React.Profiler>

? Interactive Demo: Memoization Simulation

Experience the concept of useMemo live. This demo runs a heavy calculation (Fibonacci) on the main thread.

  • First time: The browser calculates it (Slow ?).
  • Second time: It retrieves the result from cache (Instant ⚡).
Waiting for input...

? Tips & Best Practices

  • Profile first: Always identify real bottlenecks using React Profiler before applying optimizations.
  • Use memoization carefully: React.memo, useMemo, and useCallback are helpful, but overusing them can make code harder to maintain.
  • Keep components focused: Smaller components are easier to optimize and usually re-render faster.
  • Watch bundle size: Regularly analyze your bundle to avoid accidentally shipping large dependencies.
  • Test on different devices: Performance issues often show up on low-end or mobile devices first.

? Try It Yourself

  1. Use React Profiler to find a component that re-renders frequently.
  2. Apply React.memo or useCallback and observe the change in render behavior.
  3. Create a large list and improve it using virtualization.
  4. Lazy-load a component and compare the initial load time.