Práctica: Implementar streaming en una app de blog

Video
25 min~5 min lectura

Reproductor de video

Concepto clave

El streaming SSR en Next.js 15 es como un restaurante que sirve la comida por partes mientras se cocina, en lugar de esperar a que todo esté listo. Tradicionalmente, el servidor renderizaba toda la página antes de enviarla al cliente, lo que causaba tiempos de carga largos. Con streaming, el servidor envía partes de la página a medida que están disponibles, mejorando la percepción de rendimiento y la experiencia del usuario.

Imagina que estás construyendo una app de blog: la cabecera y el menú pueden cargarse inmediatamente, mientras que los posts más pesados o los comentarios se envían después. Esto se logra usando Suspense y componentes asíncronos en Server Components. El flujo es: el servidor genera un stream de HTML, el cliente lo recibe progresivamente y React hidrata los componentes cuando llegan. Esto es crucial para páginas con datos dinámicos o APIs lentas, donde no quieres que el usuario espere inactivo.

Cómo funciona en la práctica

Para implementar streaming en Next.js 15, sigue estos pasos en tu app de blog:

  1. Crea un componente de servidor asíncrono que obtenga datos, por ejemplo, para listar posts. Usa async function BlogPosts() con fetch o una librería como Prisma.
  2. Envuelve este componente en <Suspense fallback={...}> en tu página. El fallback muestra un indicador de carga (como un esqueleto) mientras se cargan los datos.
  3. Configura tu ruta en el App Router (por ejemplo, app/blog/page.tsx) para usar Server Components por defecto. Next.js 15 optimiza automáticamente el streaming cuando detecta componentes asíncronos.
  4. Prueba con datos simulados lentos: usa await new Promise(resolve => setTimeout(resolve, 2000)) para simular una API que tarda 2 segundos, y observa cómo el fallback aparece inmediatamente.

Ejemplo de código básico:

// app/blog/page.tsx
export default function BlogPage() {
  return (
    <div>
      <h1>Mi Blog</h1>
      <Suspense fallback={<p>Cargando posts...</p>}>
        <BlogPosts />
      </Suspense>
    </div>
  );
}

async function BlogPosts() {
  const posts = await fetchPosts(); // Función asíncrona
  return (
    <ul>
      {posts.map(post => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
}

Caso de estudio

En una app de blog real, como Medium o Dev.to, el streaming SSR se aplica para secciones críticas. Supongamos que tienes una página de blog con estos elementos:

SecciónTipo de datoTiempo estimado de cargaUso de streaming
Cabecera y navegaciónEstático0.1sCarga inmediata sin Suspense
Lista de postsDinámico (API)1.5sEnvuelta en Suspense con fallback
ComentariosDinámico (base de datos)2sOtro Suspense separado
Sidebar de tendenciasDinámico (cache)0.5sStreaming opcional para prioridad baja

Al implementar esto, la página empieza a renderizar en menos de 0.5s, mostrando la cabecera y un esqueleto para los posts. Luego, los posts aparecen a los 1.5s, y los comentarios a los 2s. Esto mejora el First Contentful Paint y mantiene al usuario comprometido. En producción, combínalo con Server Actions para manejar formularios de comentarios sin recargar la página.

Dato importante: Según benchmarks de Next.js, el streaming puede reducir el Time to Interactive hasta un 30% en apps con datos pesados, comparado con SSR tradicional.

Errores comunes

  • No usar fallbacks adecuados: Si omites el prop fallback en Suspense, el usuario verá un espacio vacío. Siempre incluye un indicador de carga simple, como un spinner o esqueleto HTML.
  • Anidar Suspense innecesariamente: Envolver cada componente pequeño en Suspense añade overhead. Agrupa componentes lógicos (por ejemplo, todos los posts juntos) para minimizar los límites de streaming.
  • Ignorar el orden de carga: Los componentes se stream en el orden del árbol React. Si un componente lento está arriba, bloquea los de abajo. Reorganiza para cargar primero lo crítico.
  • No manejar errores en streaming: Usa error.js en Next.js para capturar fallos en componentes asíncronos, mostrando un mensaje amigable en lugar de romper la página.
  • Olvidar optimizar datos: Streaming no es excusa para APIs lentas. Usa caching (por ejemplo, con fetch y revalidate) o paginación para reducir tiempos.

Checklist de dominio

  1. ¿Puedes crear un Server Component asíncrono que obtenga datos de una API o base de datos?
  2. ¿Sabes envolver componentes en Suspense con un fallback visualmente útil?
  3. ¿Entiendes cómo priorizar el streaming de secciones críticas sobre las menos importantes?
  4. ¿Puedes medir el impacto del streaming usando herramientas como Lighthouse o Chrome DevTools?
  5. ¿Eres capaz de integrar streaming con Server Actions para operaciones de datos en tiempo real?
  6. ¿Sabes evitar errores comunes como anidación excesiva o falta de manejo de errores?
  7. ¿Puedes explicar la diferencia entre streaming SSR y SSR tradicional en términos de experiencia de usuario?

Implementar streaming en una página de blog con Next.js 15

En este ejercicio, construirás una página de blog que use streaming SSR para cargar posts y comentarios progresivamente. Sigue estos pasos:

  1. Crea un nuevo proyecto Next.js 15 con TypeScript usando npx create-next-app@latest y selecciona el App Router.
  2. En app/blog/page.tsx, define un componente asíncrono BlogPosts que simule una API lenta: usa await new Promise(resolve => setTimeout(resolve, 2000)) y devuelve una lista de 3 posts con título y contenido.
  3. Envuelve BlogPosts en <Suspense> con un fallback que muestre <p>Cargando posts...</p>.
  4. Añade un segundo componente asíncrono Comments que simule cargar comentarios en 3 segundos, y envuélvelo en otro Suspense con su propio fallback.
  5. Ejecuta la app con npm run dev, navega a /blog, y observa cómo los posts y comentarios cargan por separado. Usa Chrome DevTools en la pestaña Network para ver el streaming en acción.
  6. Opcional: Añade un botón con una Server Action para agregar un comentario, y prueba cómo el streaming se integra con actualizaciones en tiempo real.
Pistas
  • Recuerda que los Server Components en Next.js 15 son asíncronos por defecto; no necesitas configurar nada extra para streaming.
  • Usa múltiples componentes Suspense para controlar la carga independiente de secciones, pero evita anidarlos si no es necesario.
  • Si no ves el streaming, verifica que estás usando fetch o funciones asíncronas dentro de los componentes, no en el nivel superior de la página.

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.