
How to Optimize React.js Performance
React is fast by default. But when your app grows — more components, more state, more API calls — you may start feeling it getting slower.
The good news? Most React performance problems are easy to fix if you follow some clean patterns.
In this post, I’ll explain simple and practical ways to optimize React.js performance with easy examples.
1. Avoid Unnecessary Re-renders
React re-renders a component when its state or props change. But sometimes components re-render even when nothing important changed.
Use React.memoReact.memo prevents re-render if props didn’t change.
import React from "react";
const UserCard = React.memo(({ name }) => {
console.log("Rendered");
return {name};
});
export default UserCard;Now UserCard will only re-render if name changes.
Use it for:
List items
Pure UI components
Large reusable components
2. Use useCallback for Functions
Every time a component re-renders, functions are recreated. This can cause child components to re-render.
Without optimization
const Parent = () => {
const handleClick = () => {
console.log("Clicked");
};
return ;
};Optimized with useCallback
import { useCallback } from "react";
const Parent = () => {
const handleClick = useCallback(() => {
console.log("Clicked");
}, []);
return ;
};3. Use useMemo for Heavy Calculations
If you have expensive calculations, don’t run them on every render.
import { useMemo } from "react";
const ExpensiveComponent = ({ numbers }) => {
const total = useMemo(() => {
return numbers.reduce((acc, num) => acc + num, 0);
}, [numbers]);
return Total: {total};
};4. Lazy Load Components
Don’t load everything at once. Load components only when needed.
import React, { Suspense, lazy } from "react";
const Dashboard = lazy(() => import("./Dashboard"));
function App() {
return (
Loading... 5. Optimize Lists with key
{users.map((user) => (
))}6. Avoid Large Global State
If you use global state (Context, Redux, Zustand), don’t store everything globally.
Bad pattern:
One big context
All components subscribing
Better pattern:
Split context
Use selector pattern
Keep state local when possible
7. Debounce API Calls
If user types in search input, don’t call API on every keystroke.
import { useState, useEffect } from "react";
const Search = () => {
const [query, setQuery] = useState("");
useEffect(() => {
const timeout = setTimeout(() => {
if (query) {
fetch/api/search?q=${query});
}
}, 500);
return () => clearTimeout(timeout);
}, [query]);
return (
< input
value={query}
onChange = {(e) => setQuery(e.target.value)}
placeholder="Search..."
/>
);
};8. Use Production Build
Never measure performance in development mode.
npm run buildRecap
React performance optimization is not about using every hook everywhere.
It’s about:
Preventing unnecessary re-renders
Reducing heavy computation
Splitting code
Managing state properly
Start simple. Measure first. Optimize only where needed.
Clean architecture + small components = fast React app.
That’s it. Simple and practical.

Esther Howard
Web Developer, Torikul islam
My blogs
