Il cliente che ti ha commissionato il carrello e-commerce ora ti scrive: «L'app si blocca quando carico il catalogo con 500 prodotti». Tu apri il profiler, vedi un albero di componenti che si ri-renderizza 12 volte per click. Il problema non è il framework — è che non hai mai messo un memo dove serviva, non hai caricato lazy le sezioni pesanti, e non sai nemmeno dove guardare per capire cosa rallenta. Partiamo da lì.
Quale problema risolve React memo rispetto a un componente senza memo?
React, di default, ri-renderizza un componente ogni volta che il suo stato cambia o il genitore si ri-renderizza. Se hai un ProductList che filtra 500 prodotti e ogni card contiene un ProductCard con sottocomponenti, cambiare anche solo il filtro di un carattere fa ripartire l'intero albero. Qui entra React.memo: è un higher-order component che fa un shallow comparison delle props. Se le props non sono cambiate, il componente salta la renderizzazione.
Quando usarlo e quando evitarlo
Usalo su componenti puri che ricevono le stesse props per la maggior parte dei cicli. Non usarlo su componenti con props che cambiano sempre (es. un contatore che incrementa ogni secondo) — la comparazione costa più del re-render stesso. Noi, in un progetto di dashboard per una PMI, abbiamo ridotto i re-render del 40% su una tabella di 1000 righe applicando memo solo alle righe che non cambiavano mai (es. campi lettura).
Sponsored Protocol
import React, { memo } from 'react';
const ProductCard = memo(function ProductCard({ name, price, image }) {
console.log('Rendering:', name); // utile per debug
return (
{name}
€{price.toFixed(2)}
);
});
export default ProductCard;
Checklist pratica per memo
- Il componente riceve props che cambiano raramente?
- Il componente è puro (stesso input = stesso output)?
- Hai misurato il costo della comparazione con il profiler?
- Per props oggetto/funzione, usa
useMemoouseCallbacknel genitore per evitare comparazioni sempre diverse.
Come implementare React lazy e Suspense per ridurre il bundle iniziale?
Il bundle JS iniziale di un'app React cresce rapidamente: una libreria per grafici, un editor Markdown, un modulo di amministrazione. Se carichi tutto subito, il primo caricamento è lento. React.lazy permette di caricare un componente solo quando serve, e Suspense gestisce il fallback (spinner, scheletro).
Sponsored Protocol
Esempio pratico: caricamento differito di un modulo pesante
import React, { lazy, Suspense } from 'react';
const AdminPanel = lazy(() => import('./AdminPanel'));
function App() {
const [showAdmin, setShowAdmin] = useState(false);
return (
Caricamento in corso… }>
{showAdmin && }