Concepto clave
El streaming SSR en Next.js 15 es una técnica que permite enviar partes de una página web al navegador a medida que se generan en el servidor, en lugar de esperar a que toda la página esté lista. Imagina que estás en un restaurante: en lugar de esperar a que todos los platos de tu mesa estén listos para servirte, el camarero te trae la ensalada primero, luego la sopa, y finalmente el plato principal. Cada componente se stream (transmite) cuando está listo, mejorando la percepción de velocidad para el usuario.
Esto se combina con Server Components, que se renderizan exclusivamente en el servidor, reduciendo el código JavaScript que se envía al cliente. Juntos, permiten construir aplicaciones que se sienten rápidas incluso con datos lentos o complejos. La clave está en dividir la página en chunks (fragmentos) independientes que pueden cargarse progresivamente.
Cómo funciona en la práctica
En Next.js 15, implementas streaming usando Suspense para envolver componentes que cargan datos de forma asíncrona. Por ejemplo, en un dashboard con múltiples secciones, puedes hacer que cada sección se stream de manera independiente.
Paso a paso:
- Crea un componente de servidor que use
async/awaitpara fetch de datos. - Envuelve ese componente en un
<Suspense fallback={...}>para mostrar un estado de carga. - Next.js automáticamente stream el contenido cuando los datos estén disponibles, mostrando el fallback mientras tanto.
Ejemplo básico:
// app/dashboard/page.tsx
export default function Dashboard() {
return (
<div>
<h1>Dashboard</h1>
<Suspense fallback={<p>Cargando ventas...</p>}>
<SalesChart />
</Suspense>
<Suspense fallback={<p>Cargando usuarios...</p>}>
<UserList />
</Suspense>
</div>
);
}
// app/dashboard/sales-chart.tsx
export default async function SalesChart() {
const sales = await fetchSalesData(); // Datos lentos
return <Chart data={sales} />;
}Caso de estudio
Vamos a optimizar una página de e-commerce que muestra productos, reseñas y recomendaciones. Sin streaming, el usuario espera 3 segundos a que todo cargue. Con streaming, mostramos progresivamente:
| Componente | Tiempo de carga | Acción del usuario |
|---|---|---|
| Encabezado y filtros | 0.5s | Puede interactuar inmediatamente |
| Lista de productos | 1.5s | Ve productos y hace scroll |
| Reseñas | 2.5s | Lee reseñas mientras productos cargan |
| Recomendaciones | 3.0s | Recibe sugerencias personalizadas |
Implementación en código:
// app/productos/[id]/page.tsx
export default function ProductPage({ params }) {
return (
<>
<ProductHeader productId={params.id} />
<Suspense fallback={<ProductSkeleton />}>
<ProductDetails productId={params.id} />
</Suspense>
<Suspense fallback={<ReviewsSkeleton />}>
<ProductReviews productId={params.id} />
</Suspense>
<>
);
}El streaming puede mejorar el Largest Contentful Paint (LCP) hasta en un 40% en aplicaciones con múltiples fuentes de datos.
Errores comunes
- Anidar Suspense innecesariamente: Envolver cada elemento pequeño en Suspense crea overhead. Agrupa componentes lógicos juntos.
- Olvidar fallbacks útiles: Usar
fallback={null}hace que la página parezca rota. Siempre provee un indicador de carga. - Streaming sin caché: Si los datos no se cachean, cada stream puede hacer llamadas repetidas a la API. Usa
fetchconnext: { revalidate: 60 }. - Ignorar el orden de stream: Componentes críticos (como encabezados) deben stream primero. Prioriza con
loading.jso Suspense estratégico. - No probar en red lenta: Usa DevTools para simular 3G y ver cómo se comporta el streaming.
Checklist de dominio
- Puedo explicar la diferencia entre SSR tradicional y streaming SSR.
- He implementado Suspense para al menos 2 componentes asíncronos en un proyecto.
- Sé cómo medir el impacto del streaming en Core Web Vitals.
- Puedo identificar cuándo usar Server Components vs Client Components en streaming.
- He configurado caché para datos en componentes que usan streaming.
- Puedo debuggear problemas de hidratación con streaming.
- Sé optimizar el orden de stream para mejor experiencia de usuario.
Optimiza una página de blog con streaming SSR
En este ejercicio, mejorarás una página de blog que actualmente carga todo de una vez, causando una espera larga. Implementarás streaming para cargar contenido progresivamente.
- Prepara el entorno: Crea un nuevo proyecto Next.js 15 o usa uno existente. Asegúrate de tener una página de blog con al menos tres secciones: encabezado, lista de artículos, y sidebar con categorías.
- Identifica componentes lentos: Simula datos lentos en
lista de artículosysidebarusandoawait new Promise(resolve => setTimeout(resolve, 2000))en funciones async. - Implementa Suspense: Envuelve cada componente lento en un
<Suspense>con un fallback apropiado (ej: skeleton loader). - Prioriza el stream: Asegúrate de que el encabezado se muestre primero, luego la lista de artículos, y finalmente el sidebar.
- Prueba y mide: Usa las DevTools de Chrome para simular una red lenta (3G) y verifica que los componentes se stream en el orden correcto. Revisa el LCP en Lighthouse.
- Usa el componente
loading.jsde Next.js para el fallback global si es necesario. - Considera agrupar el sidebar en un Suspense separado para que no bloquee la lista de artículos.
- Para datos simulados, crea funciones async que devuelvan arrays de objetos con titulos y contenido.
Evalua tu comprension
Completa el quiz interactivo de arriba para ganar XP.