React is fast, but that doesn’t mean your app always will be.

If you're building modern web apps with React, performance issues can sneak in as your app grows. In this post, we’ll break down common React performance problems, and show you how to fix them with easy-to-apply techniques.


🧠 Why react performance matters

React re-renders components when state or props change. That’s great for reactivity, but it can lead to:

  • Slow UI updates
  • Laggy interactions
  • Unnecessary re-renders
  • Memory leaks in large trees

👉 The key is not just building, but building efficiently.


🔍 1. Avoid unnecessary re-renders

💥 Problem:

React re-renders everything in a component tree—even if some components didn’t change.

✅ Solution:

Use React.memo to memoize functional components:

const UserCard = React.memo(({ user }) => {
  return <div>{user.name}</div>;
});

This prevents re-renders unless props actually change.


⚙️ 2. Use usememo and usecallback

🧠 Usememo:

Memoizes expensive calculations so they don't run on every render.

const sortedList = useMemo(() => {
  return list.sort(sortFunction);
}, [list]);

🧠 Usecallback:

Memoizes functions, avoiding re-creating them unnecessarily (especially useful when passing props).

const handleClick = useCallback(() => {
  console.log('Clicked');
}, []);

🧩 3. Split your code (code splitting)

Load only what the user needs. Don't ship your entire app in one bundle.

✅ Use dynamic imports:

const HeavyComponent = React.lazy(() => import('./HeavyComponent'));

<Suspense fallback={<Spinner />}>
  <HeavyComponent />
</Suspense>

🔧 This makes your app faster by reducing initial load time.


🕵️ 4. Profile and measure first

Don't guess—measure.

Use:

  • 🧪 React DevTools Profiler to find slow components
  • 🧠 Lighthouse for overall performance audits
  • 🧭 Chrome Performance Tab for deep dives

Only optimize what’s actually slow.


🔃 5. Virtualize long lists

Rendering hundreds of DOM nodes? That’s expensive.

✅ Use libraries like:

  • react-window
  • react-virtualized
import { FixedSizeList as List } from 'react-window';

<List height={300} itemCount={1000} itemSize={35} width={300}>
  {({ index, style }) => <div style={style}>Item {index}</div>}
</List>

This renders only visible items, saving memory and CPU.


💡 6. Optimize images and assets

  • Use modern image formats (WebP, AVIF)
  • Compress assets
  • Lazy-load images (loading="lazy" in <img>)
  • Use a CDN for delivery

These don’t relate to React directly, but hugely impact perceived performance.


🧪 7. Avoid anonymous functions in JSX

❌ This causes re-renders:

<MyComponent onClick={() => doSomething()} />

✅ Instead, define with usecallback or pass references:

const handleClick = useCallback(() => doSomething(), []);
<MyComponent onClick={handleClick} />

⚠️ 8. Be careful with context

React Context is powerful, but every change triggers a full re-render of all consuming components.

Use context only for:

  • Auth/session
  • Theme
  • Localization

For frequent updates (like form state or data), use other tools like:

  • Zustand
  • Redux
  • Jotai
  • Component-level state

✅ Summary checklist

  • ✅ Use React.memo, useMemo, useCallback
  • ✅ Use code-splitting and lazy loading
  • ✅ Profile before optimizing
  • ✅ Virtualize long lists
  • ✅ Optimize images and avoid large bundles
  • ✅ Avoid anonymous functions in render
  • ✅ Use Context wisely

🧠 Final thoughts

React makes building interfaces easier, but performance requires intention. With a few smart optimizations, you can dramatically improve your app's speed and responsiveness.

Start small, measure often, and remember: fast feels good