Web Development

Ottimizzazione delle performance in applicazioni React

Strategie e tecniche per migliorare le performance delle tue applicazioni React.

Ottimizzazione delle Performance in Applicazioni React

Le performance sono uno degli aspetti più critici di qualsiasi applicazione web moderna. In React, un rendering non ottimizzato può trasformare un'interfaccia fluida in un'esperienza frustrante, specialmente su dispositivi a bassa potenza. In questa guida esploriamo le tecniche fondamentali per mantenere la tua app React veloce e reattiva.

Capire il Problema: Come React Esegue il Re-render

Prima di ottimizzare, è essenziale capire quando React decide di ri-renderizzare un componente:

  • Quando cambia il state interno del componente
  • Quando cambiano le props ricevute dal genitore
  • Quando si ri-renderizza il componente genitore (anche se le props non cambiano)

Quest'ultimo punto è la causa più comune di render non necessari.

useMemo e useCallback

I due hook più usati per evitare ricalcoli costosi:

// Senza ottimizzazione - recalcola ad ogni render
function ProductList({ products, filter }) {
  const filtered = products.filter(p => p.category === filter);
  return filtered.map(p => <Product key={p.id} {...p} />);
}

// Con useMemo - ricalcola solo quando cambiano le dipendenze
function ProductList({ products, filter }) {
  const filtered = useMemo(
    () => products.filter(p => p.category === filter),
    [products, filter]
  );
  return filtered.map(p => <Product key={p.id} {...p} />);
}

useCallback è l'equivalente per le funzioni:

// La funzione viene ricreata solo se userId cambia
const handleEdit = useCallback((productId) => {
  editProduct(userId, productId);
}, [userId]);

React.memo per i Componenti

Wrappa un componente con React.memo per saltare il re-render se le props non cambiano:

const Product = React.memo(function Product({ name, price, onAdd }) {
  console.log("rendering:", name);
  return (
    <div>
      <h3>{name}</h3>
      <span>{price}€</span>
      <button onClick={onAdd}>Aggiungi</button>
    </div>
  );
});

Attenzione: React.memo usa un confronto superficiale (shallow equality). Se passi oggetti o array come props, considera una funzione di comparazione personalizzata.

Virtualizzazione delle Liste Lunghe

Renderizzare migliaia di elementi nel DOM è devastante per le performance. Usa la virtualizzazione per renderizzare solo gli elementi visibili:

import { FixedSizeList } from "react-window";

function VirtualList({ items }) {
  const Row = ({ index, style }) => (
    <div style={style}>
      <ProductCard product={items[index]} />
    </div>
  );

  return (
    <FixedSizeList
      height={600}
      itemCount={items.length}
      itemSize={80}
      width="100%"
    >
      {Row}
    </FixedSizeList>
  );
}

Code Splitting con lazy()

Carica i componenti pesanti solo quando servono:

import { lazy, Suspense } from "react";

const ChartDashboard = lazy(() => import("./ChartDashboard"));
const AdminPanel = lazy(() => import("./AdminPanel"));

function App() {
  return (
    <Suspense fallback={<Spinner />}>
      <Routes>
        <Route path="/charts" element={<ChartDashboard />} />
        <Route path="/admin" element={<AdminPanel />} />
      </Routes>
    </Suspense>
  );
}

Profiling con React DevTools

React DevTools offre un profiler integrato per identificare i colli di bottiglia:

  1. Apri DevTools → tab Profiler
  2. Clicca Record e interagisci con la UI
  3. Analizza il Flame Graph per vedere quali componenti impiegano più tempo

Best Practices

  • Evita oggetti e array inline nelle props — Creano nuovi riferimenti ad ogni render
  • Sposta lo stato in basso — Metti lo state il più vicino possibile a dove viene usato
  • Usa le chiavi corrette — Non usare mai l'index come key in liste dinamiche
  • Debounce gli input — Per ricerche e filtri in tempo reale
  • Ottimizza le immagini — Usa formati moderni (WebP, AVIF) e lazy loading nativo

Conclusioni

L'ottimizzazione in React non è una singola tecnica, ma un approccio sistematico: prima misura (DevTools Profiler), poi ottimizza. Applicare useMemo e useCallback ovunque senza misurare può addirittura peggiorare le performance per via del costo degli hook stessi.

Identifica i bottleneck reali, ottimizza dove conta davvero, e la tua app React velerà via.

Tag

Condividi

Articoli correlati