The client who commissioned your e-commerce cart is now writing: “The app freezes when loading the catalog with 500 products.” You open the profiler and see a component tree re-rendering 12 times per click. The problem isn’t the framework — it’s that you never added memo where it mattered, you never lazy-loaded heavy sections, and you don’t know where to look to find the bottlenecks. Let’s start there.
What problem does React memo solve compared to a component without memo?
By default, React re-renders a component whenever its state changes or its parent re-renders. If you have a ProductList that filters 500 products and each card contains a ProductCard with sub-components, changing even one filter character triggers the whole tree. React.memo is a higher-order component that performs a shallow comparison of props. If props haven’t changed, the component skips rendering.
When to use it and when to avoid it
Use it on pure components that receive the same props most of the time. Don’t use it on components whose props always change (e.g., a counter that increments every second) — the comparison costs more than the re-render itself. In a dashboard project for an SME, we reduced re-renders by 40% on a 1000-row table by applying memo only to rows that never changed (e.g., read-only fields).
Sponsored Protocol
import React, { memo } from 'react';
const ProductCard = memo(function ProductCard({ name, price, image }) {
console.log('Rendering:', name); // useful for debugging
return (
{name}
${price.toFixed(2)}
);
});
export default ProductCard;
Practical checklist for memo
- Does the component receive props that rarely change?
- Is the component pure (same input = same output)?
- Have you measured the comparison cost with the profiler?
- For object/function props, use
useMemooruseCallbackin the parent to avoid always-different references.
How to implement React lazy and Suspense to reduce the initial bundle?
The initial JS bundle of a React app grows fast: a chart library, a Markdown editor, an admin module. Loading everything upfront makes the first load slow. React.lazy lets you load a component only when it’s needed, and Suspense handles the fallback (spinner, skeleton).
Sponsored Protocol
Practical example: deferred loading of a heavy module
import React, { lazy, Suspense } from 'react';
const AdminPanel = lazy(() => import('./AdminPanel'));
function App() {
const [showAdmin, setShowAdmin] = useState(false);
return (
Loading… }>
{showAdmin && }