# React 19 Suspense e Concurrent Rendering: Streaming SSR e Domande di Colloquio 2026 > Guida completa a React 19 Suspense, Concurrent Rendering e Streaming SSR. Include esempi di codice pratici e le domande più frequenti nei colloqui tecnici del 2026. - Published: 2026-08-21 - Updated: 2026-08-21 - Author: Anthony Fillion-Maillet - Reading time: 5 min --- React 19 rappresenta un punto di svolta nello sviluppo di applicazioni web moderne. Con la stabilizzazione di Suspense per il data fetching e i miglioramenti al Concurrent Rendering, gli sviluppatori possono ora creare interfacce utente reattive che si caricano più velocemente e rispondono in modo fluido. Lo Streaming SSR permette di inviare progressivamente frammenti HTML al browser prima che tutti i dati siano disponibili. Questo articolo esplora i concetti fondamentali, le implementazioni pratiche e le domande più frequenti nei colloqui tecnici del 2026. > **Suspense va oltre il semplice indicatore di caricamento** > > Mentre molti sviluppatori conoscono Suspense solo come wrapper per UI di fallback, la sua vera potenza risiede nella coordinazione delle operazioni asincrone. React può così dare priorità a quali parti della UI devono essere renderizzate per prime, garantendo un'esperienza utente ottimale anche con connessioni di rete lente. In combinazione con i Server Components, Suspense diventa il componente centrale delle architetture React moderne. ## Fondamenti di React Suspense nella Versione 19 Suspense permette ai componenti React di "attendere" operazioni asincrone senza implementare logiche complesse di gestione dello stato. Il concetto si basa sul principio che i componenti possono "lanciare" una Promise durante il caricamento, che React intercetta mostrando un fallback. L'utilizzo base di Suspense si è stabilizzato con React 18, ma React 19 introduce miglioramenti significativi. L'integrazione con i Server Components è ora perfetta, e il nuovo hook `use` permette la gestione diretta delle Promise all'interno dei componenti. ```tsx import { Suspense, use } from 'react'; interface User { id: string; name: string; email: string; } function UserProfile({ userPromise }: { userPromise: Promise }) { const user = use(userPromise); return (

{user.name}

{user.email}

); } function UserProfileSkeleton() { return (
); } export default function ProfilePage() { const userPromise = fetchUser('123'); return ( }> ); } ``` La differenza fondamentale rispetto al data fetching tradizionale basato sullo stato risiede nella dichiaratività. Il componente descrive solo ciò di cui ha bisogno, non come i dati devono essere caricati. React si occupa di coordinare il processo di caricamento. ## Concurrent Rendering e il Suo Impatto Il Concurrent Rendering non è una singola funzionalità, ma un cambiamento fondamentale nel modo in cui React prioritizza e interrompe il lavoro di rendering. Tradizionalmente, un'operazione di rendering bloccava il Main Thread fino al completamento. Con il Concurrent Rendering, React può mettere in pausa il lavoro di rendering per elaborare aggiornamenti più urgenti come le interazioni dell'utente. Gli effetti pratici sono particolarmente evidenti con UI complesse. Se un utente digita durante un'operazione di rendering impegnativa, React può dare priorità all'input da tastiera e riprendere il rendering originale successivamente. ```tsx import { useState, useTransition, useDeferredValue } from 'react'; function SearchResults({ query }: { query: string }) { // Expensive computation or data fetching const results = searchDatabase(query); return (
    {results.map(result => (
  • {result.title}
  • ))}
); } export function SearchPage() { const [query, setQuery] = useState(''); const [isPending, startTransition] = useTransition(); const deferredQuery = useDeferredValue(query); const handleSearch = (e: React.ChangeEvent) => { const value = e.target.value; setQuery(value); // Immediate update for input startTransition(() => { // Deferred update for expensive rendering }); }; return (
Caricamento risultati...
}>
); } ``` La combinazione di `useTransition` e `useDeferredValue` permette un controllo granulare sulle priorità di rendering. `useTransition` contrassegna gli aggiornamenti di stato come non urgenti, mentre `useDeferredValue` fornisce un valore ritardato che può restare indietro durante carichi elevati. ## Streaming SSR con React Server Components Lo Streaming SSR rivoluziona i tempi di rendering lato server. Invece di attendere tutti i dati per poi inviare una pagina HTML completa, React inizia immediatamente a trasmettere frammenti HTML. Quando un Suspense boundary viene risolto, il server invia l'HTML corrispondente. In Next.js 16 con App Router, lo Streaming SSR è abilitato di default. Ogni Server Component racchiuso in un Suspense boundary viene automaticamente trasmesso in streaming. ```tsx // app/dashboard/page.tsx import { Suspense } from 'react'; async function RevenueChart() { const data = await fetchRevenueData(); // 2 secondi return (

Fatturato

); } async function RecentOrders() { const orders = await fetchRecentOrders(); // 500ms return (

Ordini Recenti

); } export default function DashboardPage() { return (
}> }>
); } ``` Il browser riceve prima l'HTML del layout con entrambi gli skeleton. Quando `RecentOrders` è pronto (dopo 500ms), il server trasmette l'HTML e uno script che sostituisce lo skeleton. `RevenueChart` segue dopo 2 secondi. Il Time To First Byte (TTFB) migliora drasticamente poiché il server inizia a inviare immediatamente. ## Gestione degli Errori con Error Boundaries Suspense e Error Boundaries lavorano insieme per gestire in modo dichiarativo sia gli stati di caricamento che quelli di errore. In React 19, gli Error Boundaries possono catturare anche errori asincroni che si verificano durante il rendering lato server. ```tsx 'use client'; import { Component, ReactNode } from 'react'; interface Props { children: ReactNode; fallback: ReactNode; } interface State { hasError: boolean; error: Error | null; } export class AsyncErrorBoundary extends Component { constructor(props: Props) { super(props); this.state = { hasError: false, error: null }; } static getDerivedStateFromError(error: Error): State { return { hasError: true, error }; } render() { if (this.state.hasError) { return this.props.fallback; } return this.props.children; } } // Utilizzo con Suspense function DataSection() { return (

Errore nel caricamento dei dati

} > }> ); } ``` La gerarchia è importante: gli Error Boundaries dovrebbero racchiudere i Suspense boundaries affinché gli errori durante il data fetching vengano catturati correttamente. Altrimenti, un errore potrebbe causare il crash dell'intera pagina. ## Pattern di Ottimizzazione per la Produzione In ambienti di produzione, Suspense e Streaming SSR richiedono un'attenta ottimizzazione. Troppi Suspense boundaries possono portare a un "effetto popcorn" dove i contenuti appaiono in modo scoordinato. Troppo pochi significano tempi di attesa più lunghi. ```tsx // Struttura ottimizzata con boundaries strategici export default function ProductPage({ productId }: { productId: string }) { return (
{/* Contenuto critico - streaming immediato */} }> {/* Contenuto secondario - raggruppato in un boundary */} }> {/* Contenuto terziario - può caricarsi con ritardo */} }>
); } ``` Il prefetching gioca un ruolo critico nelle performance. Con i React Server Components, i dati possono essere caricati prima che l'utente navighi. ```tsx import { prefetch } from 'react-router'; import Link from 'next/link'; function ProductCard({ product }: { product: Product }) { const handleMouseEnter = () => { // Prefetch on hover prefetch(`/products/${product.id}`); }; return ( {product.name}

{product.name}

{product.price}

); } ``` ## Domande Frequenti nei Colloqui su Suspense e Concurrent Rendering I colloqui tecnici nel 2026 testano regolarmente la comprensione di questi concetti. Ecco le domande più importanti con le relative risposte. **Domanda: Qual è la differenza tra useTransition e useDeferredValue?** `useTransition` viene utilizzato per contrassegnare gli aggiornamenti di stato come non urgenti. Restituisce un flag `isPending` e una funzione `startTransition`. `useDeferredValue` invece accetta un valore e restituisce una versione ritardata che può restare indietro durante carichi di rendering elevati. `useTransition` è per aggiornamenti di stato propri, `useDeferredValue` per props o valori esterni. **Domanda: Come funziona tecnicamente lo Streaming SSR?** Lo Streaming SSR utilizza HTTP Transfer-Encoding: chunked. Il server invia prima lo scheletro HTML con i fallback di Suspense. Quando un componente è pronto, il server invia un frammento HTML insieme a un tag `