Performance Optimization in React
Introduction
As React applications grow in size and complexity, performance becomes increasingly important. Slow rendering, unnecessary re-renders, and large data updates can affect the user experience. React provides several tools and techniques to keep applications fast and efficient.
In this chapter, you will learn how React optimizes rendering and how you can further improve performance using built-in features.
Why Performance Matters
A fast application improves user satisfaction and reduces load on devices and networks. Performance optimization ensures that components update only when necessary and that heavy operations do not slow down the interface.
Common performance issues include:
Unnecessary component re-renders
Large lists rendering all at once
Expensive calculations running repeatedly
Preventing Unnecessary Re-renders with React.memo
React.memo is a higher-order component that prevents re-rendering when props have not changed.
import React from "react";
const Child = React.memo(function Child({ value }) {
console.log("Child rendered");
return <p>{value}</p>;
});
Now Child re-renders only when the value prop changes.
Using useCallback for Functions
Functions are recreated on every render, which may cause child components to re-render. useCallback helps memoize functions.
import { useState, useCallback } from "react";
function Parent() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
console.log("Button clicked");
}, []);
return <button onClick={handleClick}>Click</button>;
}
The function reference remains stable across renders.
Using useMemo for Expensive Calculations
useMemo stores the result of a heavy computation and recalculates it only when dependencies change.
import { useMemo } from "react";
function Calculator({ number }) {
const squared = useMemo(() => number * number, [number]);
return <p>Result: {squared}</p>;
}
This avoids recalculating values unnecessarily.
Optimizing List Rendering with Keys and Lazy Loading
Large lists can slow performance. Always use proper keys and consider techniques like pagination or lazy loading.
const items = ["A", "B", "C"];
function List() {
return (
<ul>
{items.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
);
}
Efficient rendering ensures smoother UI updates.
Code Splitting with React.lazy
React.lazy allows loading components only when needed, reducing initial bundle size.
import React, { Suspense } from "react";
const About = React.lazy(() => import("./About"));
function App() {
return (
<Suspense fallback={<p>Loading...</p>}>
<About />
</Suspense>
);
}
This improves initial load performance.
Common Mistakes to Avoid
Overusing memoization unnecessarily
Forgetting dependency arrays in hooks
Rendering very large lists without optimization
Summary
In this chapter, you learned how to optimize React applications using React. memo, useCallback, and useMemo. You also explored list optimization and code splitting with React.lazy. These techniques ensure better performance and smoother user experiences as your application scales.