React Performance Optimization

Memoization, lazy loading, and code splitting for faster apps

React.memo useMemo useCallback Lazy Loading

Table of Contents

Introduction

As React applications grow larger, performance becomes very important.

Performance optimization helps:

  • Faster page loading
  • Better user experience
  • Reduced unnecessary rendering
  • Improved application efficiency

React provides several optimization techniques: React.memo, useMemo, useCallback, lazy loading, and code splitting.

React.memo

What is React.memo?

React.memo is a Higher Order Component (HOC) used to prevent unnecessary re-rendering of components. A component wrapped with React.memo only re-renders when its props change.

Without React.memo

JSXfunction Child() { console.log("Child Rendered"); return <h2>Child Component</h2>; }

Whenever the parent component updates, the child component also re-renders.

Using React.memo

JSXimport React from "react"; const Child = React.memo(() => { console.log("Child Rendered"); return <h2>Child Component</h2> }); export default Child;
  • Prevents unnecessary rendering
  • Improves performance
  • Useful for large applications

React.memo Example

JSXimport React, { useState } from "react"; const Child = React.memo(() => { console.log("Child Rendered"); return <h2>Memoized Child</h2>; }); function App() { const [count, setCount] = useState(0); return ( <div> <h1>{count}</h1> <button onClick={() => setCount(count + 1)}>Increase</button> <Child /> </div> ); } export default App;

Result: Parent re-renders, but the memoized child does not re-render unnecessarily.

useMemo Hook

What is useMemo?

useMemo is used to memoize expensive calculations. It stores computed values and recalculates only when dependencies change.

Syntax

JSXconst memoizedValue = useMemo(() => { return expensiveFunction(); }, [dependency]);

useMemo Example

JSXimport React, { useState, useMemo } from "react"; function App() { const [count, setCount] = useState(0); const expensiveCalculation = (num) => { console.log("Calculating..."); return num * 2; }; const result = useMemo(() => { return expensiveCalculation(count); }, [count]); return ( <div> <h1>Result: {result}</h1> <button onClick={() => setCount(count + 1)}>Increase</button> </div> ); } export default App;

Benefits: Avoids repeated calculations, improves performance, useful for large computations.

useCallback Hook

What is useCallback?

useCallback memoizes functions. It prevents function recreation during re-rendering.

Syntax

JSXconst memoizedFunction = useCallback(() => { }, [dependency]);

useCallback Example

JSXimport React, { useState, useCallback } from "react"; function App() { const [count, setCount] = useState(0); const handleClick = useCallback(() => { console.log("Button Clicked"); }, []); return ( <div> <h1>{count}</h1> <button onClick={() => setCount(count + 1)}>Increase</button> <button onClick={handleClick}>Click</button> </div> ); } export default App;

Benefits: Prevents unnecessary function recreation, improves rendering performance, useful with React.memo.

Difference Between useMemo and useCallback

HookPurpose
useMemoMemoizes values
useCallbackMemoizes functions

Lazy Loading in React

What is Lazy Loading?

Lazy loading loads components only when needed. Instead of loading all components initially, React loads components dynamically. This reduces initial loading time and bundle size.

React.lazy Example

JSXimport React, { Suspense } from "react"; const Home = React.lazy(() => import("./Home")); function App() { return ( <div> <Suspense fallback={<h2>Loading...</h2>}> <Home /> </Suspense> </div> ); } export default App;
ComponentPurpose
React.lazyDynamically imports component
SuspenseDisplays fallback UI while loading

Benefits: Faster initial page load, better performance, smaller bundle size.

Code Splitting

What is Code Splitting?

Code splitting divides application bundles into smaller chunks. Instead of loading the entire application at once, React loads required code only.

Large React applications can become slow because of big JavaScript bundles and longer loading times. Code splitting solves this problem.

Code Splitting Example

JSXconst About = React.lazy(() => import("./About"));

This creates a separate JavaScript chunk for the About component.

Route-Based Code Splitting

JSXimport React, { Suspense } from "react"; import { BrowserRouter, Routes, Route } from "react-router-dom"; const Home = React.lazy(() => import("./Home")); const About = React.lazy(() => import("./About")); function App() { return ( <BrowserRouter> <Suspense fallback={<h2>Loading...</h2>}> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> </Routes> </Suspense> </BrowserRouter> ); } export default App;

Performance Optimization Tips

  • Use React.memo — Avoid unnecessary component rendering
  • Use useMemo — Optimize expensive calculations
  • Use useCallback — Prevent unnecessary function recreation
  • Use lazy loading — Load components dynamically
  • Use code splitting — Reduce bundle size
  • Optimize images — Use compressed images and modern formats
  • Avoid unnecessary state — Keep state minimal

Real-World Use Cases

TechniqueUse Case
React.memoLarge component trees
useMemoFiltering large data
useCallbackPassing functions to child components
Lazy LoadingDashboard pages
Code SplittingLarge applications

Summary

In this tutorial, you learned:

  • React.memo
  • useMemo
  • useCallback
  • Lazy loading
  • Code splitting

These optimization techniques help React applications become faster, efficient, scalable, and user-friendly. Performance optimization is very important in modern React development.

React Performance Optimization MCQ Practice

10 Basic MCQs 10 Advanced MCQs

10 Basic React Performance Optimization MCQs

1

React.memo wraps:

AComponent to skip re-render if props unchanged
BRouter
Cnpm
DCSS file
Explanation: Shallow compare props by default.
2

useMemo returns:

AMemoized computed value
BMemoized component always
CDOM node
DRouter
Explanation: Recalculate only when deps change.
3

useCallback returns:

AMemoized function reference
BMemoized number only
CCSS
DPromise
Explanation: Stable callback for child memo deps.
4

React.lazy loads:

AComponent code on demand
BAll bundles upfront
CCSS only
DImages only
Explanation: Code splitting with dynamic import.
5

Suspense fallback shows:

AUI while lazy component loads
BError only
CRedux store
DRouter config
Explanation: <Suspense fallback={<Spinner />}>.
6

Unnecessary re-renders often caused by:

ANew object/function props each render
BUsing keys
CUsing fragments
DUsing JSX
Explanation: Inline {} and () => create new references.
7

Virtual DOM helps by:

AMinimizing real DOM updates
BRemoving JavaScript
CDisabling state
DUsing SQL
Explanation: Diff + reconcile batch DOM writes.
8

Profiling React app uses:

AReact DevTools Profiler
BOnly console.log
CCSS inspector only
Dpackage.json
Explanation: Record commits to find slow renders.
9

key prop on lists helps performance by:

ACorrect reconciliation
BMaking CSS faster only
CDisabling state
DRemoving fetch
Explanation: Stable keys avoid expensive DOM moves.
10

Colocating state:

AKeep state close to where needed
BPut everything in Redux always
CUse global for checkbox
DDelete components
Explanation: Limits re-render subtree scope.

10 Advanced React Performance Optimization MCQs

1

React 18 startTransition marks updates as:

ANon-urgent lower priority
BBlocking always
CServer-only
DCSS
Explanation: Keep input responsive during heavy UI updates.
2

useDeferredValue is for:

ADeferring expensive render based on lagging value
BFetching only
CRouting
DKeys
Explanation: Show stale UI while preparing new expensive tree.
3

Windowing libraries fix:

ARendering thousands of DOM nodes in lists
Bnpm speed
CJSX syntax
DRouter
Explanation: react-window renders visible rows only.
4

Custom memo comparison function when:

AProps are objects needing deep compare (carefully)
BAlways default
CNever use memo
DLists forbidden
Explanation: Use sparingly—deep compare can cost more.
5

Context performance fix:

ASplit providers / memoize value
BOne giant context always
CRemove all state
DUse innerHTML
Explanation: Avoid one context value changing for whole app.
6

Bundle analysis tool:

Awebpack-bundle-analyzer or vite visualizer
Beslint only
Cprettier
Djest only
Explanation: Find large dependencies to split or replace.
7

Avoid inline object in memoized child because:

ANew reference breaks memo
BFaster always
CRequired pattern
DHooks rule
Explanation: Hoist to useMemo or pass primitives.
8

Strict Mode double render in dev:

AHelps find side effects—not extra production cost
BDoubles production renders
CDisables memo
DRemoves lazy
Explanation: Dev-only behavior.
9

Server-side rendering improves:

AFirst contentful paint and SEO for public pages
BAll client interactivity
Cnpm install speed
DDELETE requests
Explanation: Hydration connects server HTML to React.
10

Web Workers with React used for:

AOffloading heavy CPU work off main thread
BStyling
CRouting
DKeys
Explanation: Keep UI thread responsive.

15 React Performance Optimization Interview Questions & Answers

Easy Medium Hard
1What causes unnecessary re-renders?medium
Answer: Parent re-render, context change, new prop references, state updates.
2When to use React.memo?medium
Answer: Expensive pure components receiving stable props that re-render often.
3useMemo vs useCallback?easy
Answer: useMemo for values; useCallback for stable function references.
4What is code splitting?medium
Answer: Loading parts of app on demand to reduce initial bundle size.
5How measure React performance?medium
Answer: Profiler, why-did-you-render (dev), Lighthouse, Web Vitals.
6List virtualization?hard
Answer: Render only visible items in long lists.
7Does memo always help?hard
Answer: No—memo has cost; profile first; wrong deps hurt.
8Lifting state down?medium
Answer: Move state closer to consumers to narrow re-render scope.
9useTransition example?hard
Answer: Mark tab switch or filter as transition while typing stays urgent.
10Avoid premature optimization?medium
Answer: Profile real bottlenecks before adding memo everywhere.
11Production build optimizations?medium
Answer: Minify, tree-shake, compress, lazy routes, image optimization.
12Hydration mismatch impact?hard
Answer: Forces client rework—fix SSR/client consistency.
13Debouncing expensive search?medium
Answer: Reduce filter operations while user types.
14Redux re-render note?hard
Answer: useSelector with narrow slices prevents global re-renders.
15Core Web Vitals?hard
Answer: LCP, INP, CLS—optimize loading, interactivity, layout stability.