How to Improve React App Performance with Simple Hacks π
π Why React Performance Matters
A slow React app can frustrate users, increase bounce rates, and even impact SEO. Instead of a complete rewrite, you can use simple optimizations to significantly boost your React appβs speed and efficiency.
Letβs explore proven techniques to improve performance while keeping the code clean and scalable.
β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β
1οΈβ£ Prevent Unnecessary Re-Renders with React.memo()
π§
By default, React re-renders child components even if their props havenβt changed. This can be inefficient.
β
Solution: Use React.memo()
to prevent unnecessary re-renders by memoizing components.
β Unoptimized Version
const ChildComponent = ({ name }) => {
console.log("Child Rendered!");
return <h2>Hello, {name}!</h2>;
};
const ParentComponent = () => {
const [count, setCount] = React.useState(0);
return (
<div>
<button onClick={() => setCount(count + 1)}>Increase</button>
<ChildComponent name="John" />
</div>
);
};
πΉ Issue: Even though name="John"
never changes, ChildComponent
re-renders every time the button is clicked.
β
Optimized with React.memo()
const ChildComponent = React.memo(({ name }) => {
console.log("Child Rendered!");
return <h2>Hello, {name}!</h2>;
});
π₯ Now, ChildComponent
only re-renders if name
changes!
β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β
2οΈβ£ Optimize Lists with key
and React Virtualization π₯
Large lists can slow down your app due to excessive re-renders.
β Solution:
- Use a unique
key
(not index) for lists. - Use react-window for rendering large lists efficiently.
β Unoptimized List
{items.map((item, index) => (
<div key={index}>{item.name}</div>
))}
β οΈ Issue: Using index
as key
can cause unnecessary re-renders.
β
Optimized with Unique key
{items.map((item) => (
<div key={item.id}>{item.name}</div>
))}
πΉ Why? React efficiently tracks list updates based on unique id
.
β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β
π Supercharged: Virtualized List for Large Data
import { FixedSizeList as List } from "react-window";
const MyList = ({ items }) => (
<List height={400} itemCount={items.length} itemSize={50} width="100%">
{({ index, style }) => <div style={style}>{items[index].name}</div>}
</List>
);
π₯ Now, React only renders visible items, boosting performance!
β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β
3οΈβ£ Optimize Functions with useCallback()
and useMemo()
π
β Problem: Unnecessary Function Recreation
Each re-render creates new function instances, causing unwanted re-renders in child components.
β Solution:
Use useCallback()
for Function Memoization
const ParentComponent = () => {
const [count, setCount] = React.useState(0);
const handleClick = React.useCallback(() => {
console.log("Button Clicked!");
}, []);
return <ChildComponent onClick={handleClick} />;
};
πΉ Now, handleClick
doesnβt change on every render! π
β
Optimize Expensive Calculations with useMemo()
If a component performs heavy calculations, it slows down the app. Use useMemo()
to cache results.
const expensiveCalculation = (num) => {
console.log("Calculating...");
return num * 2;
};
const MyComponent = ({ num }) => {
const result = React.useMemo(() => expensiveCalculation(num), [num]);
return <div>{result}</div>;
};
π₯ Now, the function only runs when num
changes!
β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β
4οΈβ£ Optimize Images and Assets πΈ
Large images slow down page load time. Use:
β
Lazy Loading (Load images only when needed)
β
Next.js Image Optimization (For Next.js projects)
πΉ React Lazy Loading Example
const LazyImage = ({ src, alt }) => (
<img loading="lazy" src={src} alt={alt} width="300" />
);
π₯ Now, images only load when they appear on the screen!
β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β
5οΈβ£ Split Code with React.lazy() & Suspense π
Instead of loading everything at once, load only what the user needs using code-splitting.
β
Solution: Use React.lazy()
to dynamically load components.
β Without Code-Splitting (Slow)
import HeavyComponent from "./HeavyComponent";
β οΈ Issue: Loads even if not needed!
β With Code-Splitting (Faster)
const HeavyComponent = React.lazy(() => import("./HeavyComponent"));
const App = () => (
<React.Suspense fallback={<div>Loading...</div>}>
<HeavyComponent />
</React.Suspense>
);
π₯ Now, HeavyComponent
loads only when needed!
β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β
π Final Thoughts
πΉ Summary of Performance Hacks
Optimization: β β β β Benefit:
React.memo() β β β β Prevents unnecessary re-renders
Keys & Virtualization β β β β Optimizes list renderinguseCallback()
&useMemo()
β β β β Prevents unnecessary function recreations
Code-Splitting withReact.lazy()
β β β β Reduces initial load time
Lazy Loading Images β β β β Improves loading speed
β
Which of these techniques have you used before?
π¬ Let me know in the comments! π