dev-resources.site
for different kinds of informations.
Optimizing React Performance: Avoiding Unnecessary Re-renders
Published at
12/19/2024
Categories
react
webperf
avoidrerenders
abhay
Author
abhay_yt_52a8e72b213be229
Author
25 person written this
abhay_yt_52a8e72b213be229
open
Avoiding Re-renders in React
Avoiding unnecessary re-renders in React is essential for optimizing application performance. React's reconciliation process identifies changes in the component tree and updates only the necessary parts. However, improper state management, props passing, or component structure can lead to redundant re-renders.
Techniques to Avoid Unnecessary Re-renders
-
Use
React.memo
React.memo
prevents re-renders of functional components if their props haven’t changed.
import React from "react";
const Child = React.memo(({ name }) => {
console.log("Child rendered");
return <div>Hello, {name}</div>;
});
function Parent() {
const [count, setCount] = React.useState(0);
return (
<div>
<button onClick={() => setCount(count + 1)}>Increment</button>
<Child name="React" />
</div>
);
}
export default Parent;
- Without
React.memo
,Child
would re-render every time the parent renders, even ifname
remains unchanged. -
React.memo
ensuresChild
renders only when itsname
prop changes.
-
Use
useCallback
for Functions React re-creates functions on every render, which may trigger re-renders if passed as props. UseuseCallback
to memoize functions.
import React, { useState, useCallback } from "react";
const Child = React.memo(({ onClick }) => {
console.log("Child rendered");
return <button onClick={onClick}>Click Me</button>;
});
function Parent() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
console.log("Button clicked");
}, []);
return (
<div>
<button onClick={() => setCount(count + 1)}>Increment</button>
<Child onClick={handleClick} />
</div>
);
}
export default Parent;
- Without
useCallback
,handleClick
would be recreated on every render, causingChild
to re-render. -
useCallback
memoizeshandleClick
, preventing unnecessary updates.
-
Use
useMemo
for Expensive Calculations UseuseMemo
to memoize computed values and avoid re-calculations on every render.
import React, { useState, useMemo } from "react";
function Parent() {
const [count, setCount] = useState(0);
const [other, setOther] = useState(0);
const expensiveCalculation = useMemo(() => {
console.log("Expensive calculation");
return count * 2;
}, [count]);
return (
<div>
<div>Result: {expensiveCalculation}</div>
<button onClick={() => setCount(count + 1)}>Increment Count</button>
<button onClick={() => setOther(other + 1)}>Increment Other</button>
</div>
);
}
export default Parent;
-
useMemo
ensures the expensive calculation is re-computed only whencount
changes.
- Avoid Inline Functions and Objects as Props Inline functions and objects are recreated on every render and can trigger re-renders.
Problematic Example:
const Child = React.memo(({ config }) => {
console.log("Child rendered");
return <div>Config: {JSON.stringify(config)}</div>;
});
function Parent() {
const config = { color: "blue" }; // Re-created on every render
return <Child config={config} />;
}
Solution: Use useMemo
for Objects:
function Parent() {
const config = React.useMemo(() => ({ color: "blue" }), []);
return <Child config={config} />;
}
- Split Components into Smaller Pieces Break large components into smaller, reusable pieces. This limits the scope of updates.
const Counter = React.memo(({ count }) => {
console.log("Counter rendered");
return <div>Count: {count}</div>;
});
function App() {
const [count, setCount] = useState(0);
const [name, setName] = useState("");
return (
<div>
<Counter count={count} />
<input
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Enter name"
/>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
- Only
Counter
will re-render whencount
changes, not the input field.
-
Avoid Re-rendering with Context API
Context updates trigger re-renders for all consuming components. Use selective context or libraries like
zustand
orReact Query
.
Using Selector:
const CounterContext = React.createContext();
function CounterProvider({ children }) {
const [count, setCount] = useState(0);
return (
<CounterContext.Provider value={{ count, setCount }}>
{children}
</CounterContext.Provider>
);
}
function DisplayCount() {
const { count } = React.useContext(CounterContext);
console.log("DisplayCount rendered");
return <div>Count: {count}</div>;
}
function IncrementButton() {
const { setCount } = React.useContext(CounterContext);
console.log("IncrementButton rendered");
return <button onClick={() => setCount((c) => c + 1)}>Increment</button>;
}
function App() {
return (
<CounterProvider>
<DisplayCount />
<IncrementButton />
</CounterProvider>
);
}
- Here,
DisplayCount
andIncrementButton
render independently.
- Avoid Updating Parent State from Child Updating parent state from a child can force the parent and all its children to re-render. Pass handlers sparingly.
- Optimize Lists with Keys React needs unique keys for list items to avoid unnecessary re-renders.
const List = ({ items }) => {
return (
<ul>
{items.map((item) => (
<li key={item.id}>{item.name}</li>
))}
</ul>
);
};
Ensure key
is unique and stable.
Tools to Detect Re-renders
- React Developer Tools: Inspect which components re-rendered.
-
why-did-you-render
Library: Logs unnecessary re-renders.
Conclusion
Avoiding unnecessary re-renders improves application performance, reduces rendering overhead, and enhances user experience. By understanding React’s rendering behavior and using tools like React.memo
, useMemo
, and useCallback
, you can optimize your components effectively.
webperf Article's
30 articles in total
Redefining Web Performance Standards with INP
read article
How to avoid frontend tech making us resentful
read article
Understanding PHP-FPM: Key Differences from Traditional PHP Processes and Benefits
read article
How Mentimeter deliver reliable live experiences at scale
read article
The Art of Prefetching and Preloading: Enhancing Web Performance
read article
The curious case of the paragraph with the bad CLS
read article
JavaScript Frameworks - Heading into 2025
read article
Technical SEO for Developers: Mastering Site Structure and Performance
read article
Extending Lighthouse for custom image and video optimization analysis
read article
Assassin ⚡️ - An open source, free database for killing slow webpages
read article
A Comprehensive Guide to Web Vitals: Metrics That Matter for Performance
read article
Why should you care about website performance?
read article
Screener.in Search API: A Performance Checkup! 🔎
read article
How Sportsbet handles 4.5M daily chat messages on its 'Bet With Mates' platform
read article
Enhancing React Performance with Concurrent Rendering
read article
Optimizing React Performance: Avoiding Unnecessary Re-renders
currently reading
Master React Profiler: Optimize Your App's Performance
read article
Lightweight, Transparent, Animated: Get All of Them by WebP Format
read article
Prerender Pages in Browser For Faster Page Load
read article
How we optimized perceived performance to improve our KPIs: a Hotjar case study
read article
Sites speed optimisation is a destination, not a journey
read article
How to Build a High-Performance WordPress Website: A Developer’s Guide
read article
Performance Optimization in React
read article
Subsequent Page Load Optimization 🚀
read article
How to Build Blazing Fast Websites with Any Framework
read article
Everything to know about Mobile App Performance Test Tools, Metrics, & Techniques
read article
Efficient State Management in Next.js: Best Practices for Scalable Applications
read article
Top 5 Tips to Supercharge Your Express.js App for Lightning-Fast Performance
read article
A useState performance tip you may not have known
read article
🚀 V8 Engine Secrets How We Slashed Memory Usage by 66% with TypedArrays
read article
Featured ones: