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.
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.
// 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>;
});
// useCallback memoizes event handlers
const handleClick = useCallback(() => {
console.log("Clicked!");
}, []);
// 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>;
}
// 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>
);
}
// Lazy load components using React.lazy and Suspense
const Dashboard = React.lazy(() => import("./Dashboard"));
<Suspense fallback={<div>Loading...</div>}>
<Dashboard />
</Suspense>
// 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>
Experience the concept of useMemo live. This demo runs a heavy calculation (Fibonacci) on the main thread.
React.memo, useMemo, and useCallback are helpful, but overusing them can make code harder to maintain.React.memo or useCallback and observe the change in render behavior.