Back to All Guides
Web Development9 min readPublished: May 15, 2026Updated: August 12, 2026

React Performance Optimization: Memoization, Code Splitting & Profiling

Practical techniques to eliminate unnecessary re-renders, optimize heavy state trees, and boost React app responsiveness.

Vyuhantrix Team
Vyuhantrix Team
Web & Systems Engineering · Vyuhantrix

Why React Apps Get Slow#

React's declarative component model makes building user interfaces intuitive. However, as applications grow, common patterns cause performance degradation: unnecessary component re-renders, large uncompressed bundles, and heavy synchronous calculations blocking the browser's UI thread.

This guide provides practical, actionable techniques to optimize React applications.


1. When to Use `useMemo` and `useCallback`#

In React, every time a parent component re-renders, all child components re-render by default, and all internal functions and objects are recreated.

When to use `useMemo`: Use `useMemo` only for computationally expensive calculations (like filtering or sorting 1,000+ items):

tsx
import { useMemo } from "react";

export function ArticleList({ articles, searchQuery }: { articles: Article[]; searchQuery: string }) {
  // Memoize filtered results so it only recalculates when articles or query changes
  const filteredArticles = useMemo(() => {
    return articles.filter((article) =>
      article.title.toLowerCase().includes(searchQuery.toLowerCase())
    );
  }, [articles, searchQuery]);

  return (
    <div className="grid gap-4">
      {filteredArticles.map((a) => (
        <ArticleCard key={a.slug} article={a} />
      ))}
    </div>
  );
}

2. Preventing Re-renders with `React.memo`#

Wrap pure visual components with React.memo so they only re-render if their props change:

tsx
import React from "react";

interface TagPillProps {
  label: string;
  onClick: (tag: string) => void;
}

export const TagPill = React.memo(function TagPill({ label, onClick }: TagPillProps) {
  return (
    <button
      onClick={() => onClick(label)}
      className="px-3 py-1 bg-gray-100 rounded-full text-xs hover:bg-gray-200"
    >
      #{label}
    </button>
  );
});

3. State Colocation: The Secret to Fast React Apps#

The #1 cause of unnecessary re-renders is placing local UI state too high in the component tree.

Rule of Thumb: Keep state as close as possible to the component that actually uses it. If only a modal dialog cares whether it is open or closed, keep isOpen state inside the modal trigger, not in the global root layout!


5. Eliminating Anonymous Function Prop Re-creations#

A common source of unnecessary re-renders in React is passing inline arrow functions to memoized child components:

tsx
// BAD: Recreates a new function on every single render, breaking React.memo!
<MemoizedUserCard user={user} onDelete={() => handleDelete(user.id)} />

// GOOD: Stabilize the handler with useCallback
const handleDeleteUser = useCallback((userId: string) => {
  setUsers((prev) => prev.filter((u) => u.id !== userId));
}, []);

<MemoizedUserCard user={user} onDelete={handleDeleteUser} />

6. React Performance Optimization Checklist#

  • [ ] Use React DevTools Profiler to identify components rendering longer than 16ms.
  • [ ] Colocate state: keep local modal and dropdown state inside isolated leaf components.
  • [ ] Use useMemo only for expensive sorting/filtering on 500+ items.
  • [ ] Use useCallback when passing callbacks to React.memo child components.
  • [ ] Lazy-load heavy dialogs and interactive charting components using next/dynamic.

7. Optimizing Context API & State Stores (Zustand)#

React Context is designed for low-frequency state changes (such as theme toggles or user authentication). Using React Context for high-frequency updates (such as mouse coordinates, form inputs, or live WebSocket tickers) triggers re-renders across all consuming components.

The Solution: Granular Selectors with Zustand Modern React applications use lightweight stores like **Zustand**, which support atomic selector subscriptions:

typescript
import { create } from "zustand";

interface AppStore {
  searchQuery: string;
  isSidebarOpen: boolean;
  setSearchQuery: (query: string) => void;
  toggleSidebar: () => void;
}

export const useAppStore = create<AppStore>((set) => ({
  searchQuery: "",
  isSidebarOpen: false,
  setSearchQuery: (searchQuery) => set({ searchQuery }),
  toggleSidebar: () => set((state) => ({ isSidebarOpen: !state.isSidebarOpen })),
}));

// Component only re-renders when searchQuery changes, ignoring isSidebarOpen!
export function SearchInput() {
  const searchQuery = useAppStore((state) => state.searchQuery);
  const setSearchQuery = useAppStore((state) => state.setSearchQuery);

  return (
    <input
      type="text"
      value={searchQuery}
      onChange={(e) => setSearchQuery(e.target.value)}
      className="p-2 border rounded"
    />
  );
}

8. Frequently Asked Questions (FAQ)#

Q: Does React.memo do a deep or shallow comparison of props? By default, React.memo performs a **shallow comparison** of complex props (objects, arrays, functions). If you pass a new object literal like `style={{ color: 'red' }}` or an inline array on every render, the shallow equality check fails and the component will still re-render. Always extract static objects outside component bodies!

Q: Should I wrap every single React component in React.memo? No. Memoization has a computational cost (storing previous props in memory and checking equality on every render). For simple presentational components with lightweight DOM trees, standard re-rendering is faster than the overhead of memoization.

Article Note & VerificationThis guide was written and reviewed by the Vyuhantrix Team for educational and practical accuracy. For framework-specific breaking changes, verify against the official documentation of the relevant project. Last updated: August 12, 2026. Disclaimer
Tags:#React#Performance#Web Development#JavaScript
Vyuhantrix Team

Published by

Vyuhantrix Team

Web & Systems Engineering · Vyuhantrix

Vyuhantrix is an open technology learning platform based in Ahmedabad, India, publishing step-by-step programming tutorials, system design breakdowns, and free developer tools.