Cambiar tema

Next.js SSR vs SSG vs ISR: guía para elegir la estrategia de renderizado

Easton editorial illustration: server-client bridge

«¿Por qué tarda tres segundos en cargar la home?» El jefe miraba la pantalla y el waterfall de Chrome DevTools: el TTFB rojo se estiraba como una serpiente. Fue la primera vez que entendí que quizá habíamos elegido mal la estrategia de renderizado desde el principio.

No es un caso aislado. En los Issues de Next.js en GitHub, cada día alguien pregunta: «¿SSR o SSG?», «¿Por qué ISR no funciona?». Antes yo también andaba perdido: leía la documentación y en proyectos reales seguía sin saber qué elegir.

Quizá te suene:

  • Usaste SSR y la carga inicial se volvió insoportable
  • Elegiste SSG y cada actualización obliga a reconstruir todo el sitio
  • ISR parecía ideal, pero tras configurarlo no hace nada

La verdad es que no hay una estrategia «mejor», solo la más adecuada. Hoy vamos a aclarar qué escenario pide cuál y cómo evitar las trampas habituales.

40-60%
SSG más rápido que SSR
Datos AWS
50ms
TTFB de SSG
Datos oficiales Vercel
200-500ms
TTFB de SSR
Datos oficiales Vercel
2.3s→0.8s
Mejora con ISR
E-commerce real
Source: Datos oficiales de AWS y Vercel, y casos reales

Primero lo básico: qué son las tres estrategias

Antes de elegir, aclaremos los conceptos. Lo explico de la forma más directa posible.

SSG (Static Site Generation): el bento preparado de antemano

Imagina una tienda de bentos: cada mañana preparas 100 y los dejas en mostrador; el cliente entra y se los lleva. Así funciona SSG.

En concreto:

  • Cuándo se genera: al ejecutar next build, Next.js genera el HTML de todas las páginas
  • Cuando el usuario visita: la CDN devuelve HTML ya generado, muy rápido
  • Cuándo conviene: páginas que cambian poco, como web corporativa, ficha de producto o artículo de blog

Ventajas claras:

  • Velocidad altísima. Según AWS, SSG carga un 40-60% más rápido que SSR
  • TTFB (time to first byte) suele estar por debajo de 50 ms, según Vercel
  • Casi cero carga en el servidor; aguanta mucho tráfico
  • Coste bajo; alojar archivos estáticos es barato

Pero tiene límites:

  • ¿Contenido actualizado? Hay que reconstruir todo el sitio
  • Muchas páginas alargan el build; miles pueden tardar media hora
  • No admite personalización; todos ven lo mismo

En pocas palabras, SSG cambia velocidad por «preparar con antelación».

SSR (Server-Side Rendering): cocinar al momento

Misma tienda, pero ya no preparas bentos. El cliente pide y cocinas en el acto. Eso es SSR.

En concreto:

  • Cuándo se genera: en cada petición, el servidor genera HTML al vuelo
  • Cuando el usuario visita: espera mientras consultas BD, llamas APIs y renderizas
  • Cuándo conviene: contenido en tiempo real o personalizado

Ventajas:

  • Contenido siempre fresco, datos del momento
  • Personalización según cookie, permisos o preferencias
  • Acceso a información solo disponible en la petición (cabeceras, query params)

Pero el coste es alto:

  • Más lento: TTFB entre 200-500 ms según Vercel
  • Más presión en el servidor con mucho tráfico
  • Coste mayor al mantener servidores activos

Caso real: un e-commerce con SSR tardaba 2,3 s en la carga inicial; al pasar a ISR bajó a 0,8 s.

ISR (Incremental Static Regeneration): bento preparado + cocina periódica

Esta vez eres más listo: preparas bentos, pero los renuevas cada cierto tiempo (por ejemplo, cada hora). La mayoría recibe comida lista, pero no demasiado antigua. Eso es ISR.

En concreto:

  • Build inicial: next build genera HTML estático (como SSG)
  • Actualizaciones: según revalidate, se regenera en segundo plano
  • Cuando el usuario visita: suele recibir HTML cacheado (rápido); si caducó, se actualiza en background

Es un equilibrio:

  • Velocidad de SSG (archivo estático)
  • Frescura de SSR (contenido que se renueva)
  • Sin reconstruir todo el sitio cada vez

Configuración sencilla (App Router):

// app/posts/[id]/page.tsx
export const revalidate = 60; // revalidar tras 60 segundos

export default async function Post({ params }) {
  const post = await getPost(params.id);
  return <div>{post.content}</div>;
}

Pero hay trampas:

  • ¿No funciona? Quizá pruebas en desarrollo (next dev); ISR solo en producción (next build + next start)
  • ¿Plataforma sin soporte? Vercel lo soporta nativamente; otras pueden requerir configuración extra

ISR es la estrategia que más uso hoy: resuelve los dolores de SSG y SSR.

Árbol de decisión: qué estrategia en cada escenario

Conceptos claros. Ahora lo importante: ¿cuál usar en tu proyecto?

No te agobies; aquí tienes un flujo paso a paso.

Paso 1: tres preguntas clave

Pregunta 1: ¿El contenido debe personalizarse?

Si la página cambia según identidad, permisos o preferencias del usuario, usa SSR.

Escenarios típicos:

  • Panel de usuario (datos distintos por persona)
  • Perfil personal
  • Carrito
  • Cualquier página tras autenticación

¿Por qué? Lo personalizado no se puede pregenerar; hay que generarlo en la petición.

Pregunta 2: ¿Con qué frecuencia cambia el contenido?

Esto decide entre SSG e ISR.

  • Cada pocos segundos o minutos: SSR

    • Cotizaciones, marcadores deportivos, chat
    • Alta exigencia de tiempo real; SSR es la opción
  • Cada minutos u horas: ISR

    • Noticias, inicio de blog, listados, stock de e-commerce
    • revalidate: 300 (5 min): rápido y relativamente fresco
  • Poco o solo con cambios manuales: SSG

    • Web corporativa, ficha de producto, documentación
    • Puede pasar semanas o meses sin cambios

Pregunta 3: ¿Cuánto tráfico hay?

El volumen afecta coste y rendimiento.

  • Tráfico muy alto (millones de PV/día): prioriza SSG o ISR

    • Archivos estáticos en CDN: bajo coste, buen rendimiento
    • SSR con mucho tráfico dispara coste y carga
  • Tráfico medio-bajo: las tres valen

    • Si necesitas tiempo real, SSR también encaja
    • Pero si ISR sirve, ¿por qué no usarlo?

Paso 2: tabla rápida por escenario

SSG:

  • ✅ Web corporativa
  • ✅ Ficha de producto, precios
  • ✅ Landing de marketing
  • ✅ Detalle de artículo (sin edits posteriores)
  • ✅ Documentación técnica, API
  • ✅ Centro de ayuda, FAQ

Palabra clave: estático, público, poco actualizado

SSR:

  • ✅ Feed social (estilo Facebook/Twitter)
  • ✅ Panel personal del usuario
  • ✅ Carrito, pedidos
  • ✅ Panel de datos en vivo
  • ✅ Resultados de búsqueda (según query)
  • ✅ Páginas autenticadas (según cookie)

Palabra clave: dinámico, personalizado, tiempo real

ISR (mi favorita):

  • ✅ Inicio de blog, listado de artículos
  • ✅ Sitio de noticias
  • ✅ Ficha de producto (precio/stock periódicos)
  • ✅ Hilo de foro (comentarios/likes con retraso aceptable)
  • ✅ Plataforma UGC (frecuente pero no segundo a segundo)
  • ✅ Tiempo, tipos de cambio

Palabra clave: actualización periódica, retraso aceptable, alto tráfico

Paso 3: mezclar estrategias es lo normal

Error común: pensar que todo el sitio debe usar una sola estrategia.

La mayoría de proyectos mezclan:

  • Inicio y listados con ISR (mucho tráfico, actualización periódica)
  • Detalle de producto con SSG (estable) o ISR (precio/stock cambian)
  • Panel de usuario con SSR (personalización)
  • «Sobre nosotros» y contacto con SSG (estático)

Un e-commerce de nuestro equipo:

  • Inicio (ISR, cada 10 min)
  • Listado de productos (ISR, 5 min)
  • Detalle (ISR, 3 min; el stock cambia)
  • Carrito (SSR, tiempo real)
  • Área de usuario (SSR, personalizado)
  • «Sobre nosotros», privacidad (SSG, casi estático)

Así equilibras rendimiento y frescura.

Regla en una frase

Si sigues dudando:

Estático → SSG, tiempo real → SSR, actualización periódica → ISR

Cuando no estés seguro, prueba ISR primero: es la más equilibrada y la que menos falla.

Tres trampas habituales y cómo resolverlas

Pasemos a lo práctico. Estas tres las he pisado yo; probablemente te tocarán a ti.

Trampa 1: revalidate de ISR que no hace nada

Síntoma: Configuras revalidate: 60 pensando que la página se actualiza cada minuto, esperas… y el contenido sigue igual.

Mi frustración: La primera vez con ISR me quedé dos días atascado. Documentación, cambios de config, nada.

Tres causas:

  1. ISR no funciona en desarrollo

    La más común. En next dev, ISR no opera; solo en producción.

    Solución:

   # No pruebes ISR con next dev
   # Construye y arranca primero
   npm run build
   npm run start

   # Luego visita la página
   
  1. Plataforma sin soporte nativo

    No todas soportan ISR igual. Vercel (oficial de Next.js) va bien; otras requieren extras.

    Netlify: instala @netlify/plugin-nextjs.

    Comprobar: busca en la documentación de tu plataforma «Next.js ISR support».

  2. La caché CDN anula ISR

    Si delante de Next.js hay CDN o proxy inverso (Cloudflare), puede cachear toda la respuesta y bloquear la regeneración.

    Solución: que la CDN respete Cache-Control o use TTL corto en páginas ISR.

Consejo: Tras configurar ISR, prueba en producción. console.log(new Date()) ayuda a ver si revalidate actúa.

Trampa 2: SSR tan lento que desespera

Síntoma: Con SSR, la pantalla en blanco dura 2-3 s y el usuario se va.

Caso real: Un proyecto usaba SSR en la home para usuario y recomendaciones. TTFB de 1,2 s más render: 3 s hasta ver contenido. El jefe no quedó contento.

Por qué va lento:

Suele ser la obtención de datos en el servidor:

  • APIs externas lentas
  • Consultas sin índice o complejas
  • Peticiones en serie
  • Servidor débil o lejos geográficamente

Cuatro soluciones:

  1. Streaming SSR y Suspense (React 18+)

    No esperes todos los datos; devuelve el marco y transmite el resto.

    // app/dashboard/page.tsx
    import { Suspense } from 'react';
    
    export default function Dashboard() {
      return (
        <div>
          <h1>Panel de usuario</h1>
          {/* Parte rápida */}
          <UserInfo />
    
          {/* Datos lentos con Suspense */}
          <Suspense fallback={<div>Cargando estadísticas...</div>}>
            <SlowStats />
          </Suspense>
        </div>
      );
    }
    

   El usuario ve la página antes; mejor experiencia.

2. **Peticiones en paralelo**

   

```typescript
   // ❌ Serie: lento
   const user = await getUser();
   const posts = await getPosts(user.id);

   // ✅ Paralelo: más rápido
   const [user, posts] = await Promise.all([
     getUser(),
     getPosts()
   ]);
   
  1. Valorar ISR

    A veces crees que necesitas SSR, pero ISR basta.

    Pregúntate: ¿hace falta tiempo real? Si un retraso de 1 minuto vale, usa ISR.

    Esa home pasó a ISR (revalidate: 60): de 3 s a 0,7 s.

  2. Desplegar en Edge

    En Vercel, Edge Functions ejecuta SSR en nodos CDN globales: menos latencia.

   // app/api/data/route.ts
   export const runtime = 'edge'; // solo esta línea
   

Trampa 3: build SSG eterno

Síntoma: Miles de páginas y next build tarda 20-30 min o falla por timeout.

Escenario: E-commerce con 5000 productos, blog con 3000 artículos; SSG genera HTML de cada uno en el build.

Por qué tarda:

SSG genera todo en el build. Más páginas, más tiempo. Muchas ni se visitan (productos de cola larga, artículos viejos).

Soluciones:

  1. Estrategia fallback

    No generes todo; solo lo popular, el resto bajo demanda.

   // app/posts/[id]/page.tsx
   export async function generateStaticParams() {
     // Solo los 100 artículos más populares
     const posts = await getTopPosts(100);
     return posts.map(post => ({ id: post.id }));
   }

   // El resto se genera en la primera visita
   export const dynamicParams = true;
   
  1. Combinar con ISR

    En el build: inicio y populares. El resto con ISR bajo demanda.

    Build más corto; el usuario no nota lentitud gracias a la caché.

  2. Builds incrementales

    Vercel regenera solo páginas cambiadas. Actualizar un artículo no obliga a reconstruir todo.

    Otras plataformas pueden requerir lógica propia.

Resultado real:

Un blog con 2000 artículos: SSG puro, 15 min de build. Después:

  • Build de las 50 más recientes
  • Resto con dynamicParams = true
  • Todas las fichas con ISR (revalidate: 3600)

Build: 2 min. Velocidad de acceso igual.

Novedades de Next.js 15: React Server Components y PPR

Dos novedades que no son «estrategias» puras, pero cambian cómo construimos páginas.

React Server Components (RSC): SSR a nivel de componente

Con App Router (Next.js 13+) ya usas Server Components.

¿Diferencia con SSR clásico?

  • SSR clásico: toda la página en el servidor
  • RSC: por defecto en servidor; solo lo interactivo en cliente

Beneficios:

  1. Bundle JS más pequeño

    El código de Server Component no va al cliente. Next.js indica 30-50% menos JavaScript.

    Carga más rápida; menos calor en el móvil.

  2. Acceso directo al backend

    Server Component puede consultar BD o leer archivos sin API intermedia.

    // app/posts/page.tsx
    // Server Component: consulta directa a BD
    async function getPosts() {
      const posts = await db.posts.findMany();
      return posts;
    }
    
    export default async function PostsPage() {
      const posts = await getPosts();
      return (
        <div>
          {posts.map(post => (
            <PostCard key={post.id} post={post} />
          ))}
        </div>
      );
    }
    

**Recomendación práctica**:

- Server Component por defecto (App Router)
- Client Component (`'use client'`) solo donde haga falta interactividad
- Datos y UI estática en Server; botones, formularios y animaciones en Client

SEO de SSR con bundle pequeño.

### Partial Prerendering (PPR): estático + dinámico en una página

PPR (Next.js 15, experimental) mezcla partes estáticas y dinámicas **en la misma página**.

**Ejemplo**:

Ficha de producto:
- Descripción e imágenes (estático, en el build)
- Stock y precio (dinámico, en la petición)

PPR prerenderiza lo estático y calcula lo dinámico en cada request: rápido y fresco.

**Uso**:

```tsx
// next.config.js
module.exports = {
  experimental: {
    ppr: true,
  },
};

// app/products/[id]/page.tsx
export const experimental_ppr = true;

export default function ProductPage({ params }) {
  return (
    <div>
      {/* Estático: generado en el build */}
      <ProductDescription id={params.id} />

      {/* Dinámico: en cada petición */}
      <Suspense fallback={<div>Cargando...</div>}>
        <DynamicStock id={params.id} />
      </Suspense>
    </div>
  );
}

Importante:

PPR sigue siendo experimental; no lo uses en producción crítica. Prueba en páginas secundarias.

Cuando madure (¿Next.js 16?), será muy potente.

¿Cómo encaja con SSR/SSG/ISR?

  • RSC + SSG: Server Component estático por defecto; encaja perfecto
  • RSC + ISR: Server Component + revalidate
  • RSC + SSR: rutas dinámicas o dynamic = 'force-dynamic'
  • PPR: fusión avanzada de SSG y SSR

RSC es la base arquitectónica; SSG/SSR/ISR son estrategias encima. Se complementan.

Conclusión

Volvamos al inicio: ¿cómo elegir SSR, SSG o ISR?

No hay respuesta única. Cada proyecto, tráfico y presupuesto son distintos. Con tres preguntas la elección se simplifica:

  1. ¿Hace falta personalización? → SSR
  2. ¿Con qué frecuencia cambia? → tiempo real SSR, periódico ISR, raro SSG
  3. ¿Cuánto tráfico? → mucho tráfico: SSG o ISR

¿Recuerdas al jefe preguntando «por qué tan lento»? Cambiamos esa home de SSR a ISR (revalidate: 60): de 3 s a 0,8 s. Mejor para él y para el usuario.

Recomendaciones:

  • Si dudas, prueba ISR: equilibrio entre velocidad y frescura
  • Tras publicar, mide con Performance de Chrome DevTools: TTFB, FCP, etc.
  • Mezcla estrategias por página; no seas rígido

La estrategia no es fija. Crece el proyecto, sube el tráfico, cambian requisitos: puedes ajustar. Next.js facilita el cambio.

Espero que evites algunas trampas. Si tienes experiencias o historias de errores, compártelas en comentarios.

FAQ

¿Cuál es la diferencia principal entre SSR, SSG e ISR?
SSG genera todo el HTML en el build; el usuario recibe archivos estáticos con TTFB habitualmente por debajo de 50 ms: rápido, pero actualizar contenido exige reconstruir. SSR genera HTML en cada petición con TTFB entre 200-500 ms: contenido fresco, pero carga inicial más lenta. ISR combina ambos: HTML estático en el build y regeneración en segundo plano según revalidate; velocidad de SSG y frescura de SSR.
¿Cuándo usar SSG, SSR o ISR?
SSG: páginas estáticas, públicas y poco actualizadas (web corporativa, producto, detalle de artículo). SSR: páginas dinámicas, personalizadas y en tiempo real (panel de usuario, carrito, datos en vivo). ISR: páginas con actualización periódica, retraso aceptable y alto tráfico (inicio de blog, noticias, ficha de producto). Regla: estático → SSG, tiempo real → SSR, actualización periódica → ISR. Si dudas, empieza con ISR.
¿Por qué no funciona revalidate en ISR?
Tres causas habituales: 1) Probar en desarrollo (next dev); ISR solo funciona en producción (next build + next start). Hay que construir y probar después. 2) La plataforma de despliegue no lo soporta; Vercel lo soporta nativamente, otras (Netlify) requieren plugin. 3) La caché CDN anula ISR; hay que configurar la CDN para respetar Cache-Control. Prueba en producción y usa console.log(new Date()) para verificar la hora de generación.
¿Qué hacer si SSR carga lento al inicio?
Opciones: 1) Streaming SSR y Suspense: devuelve el marco de la página y transmite los datos cuando lleguen. 2) Peticiones en paralelo con Promise.all en lugar de secuenciales. 3) Valorar ISR si un retraso de 1 minuto es aceptable (un caso pasó de 3 s a 0,7 s). 4) Desplegar en Edge con Edge Runtime para reducir latencia. Analiza el cuello de botella: API lenta, consultas lentas, peticiones secuenciales o servidor débil.
¿Qué hacer si el build SSG tarda demasiado?
Soluciones: 1) Estrategia fallback: generar solo páginas populares y el resto bajo demanda (generateStaticParams con contenido popular y dynamicParams = true). 2) Combinar con ISR: en el build solo inicio y páginas populares; el resto con ISR bajo demanda. 3) Builds incrementales (Vercel lo soporta; otras plataformas requieren implementación propia). Caso real: 2000 artículos pasaron de SSG puro (15 min) a fallback + ISR (2 min) sin perder velocidad de acceso.
¿Se pueden mezclar distintas estrategias de renderizado?
Sí, y es la mejor práctica. Ejemplos: inicio y listados con ISR (mucho tráfico, actualización periódica), detalle de producto con SSG (estable) o ISR (precio/stock cambian), panel de usuario con SSR (personalización), «Sobre nosotros» con SSG (estático). Caso e-commerce: inicio ISR (10 min), listado ISR (5 min), detalle ISR (3 min), carrito SSR (tiempo real), área de usuario SSR, «Sobre nosotros» SSG.
¿Qué relación hay entre React Server Components y SSR/SSG/ISR?
RSC es la evolución arquitectónica de Next.js; SSG/SSR/ISR son estrategias de renderizado sobre esa base y se complementan. RSC se renderiza por defecto en el servidor y reduce el JavaScript del cliente un 30-50%. Combinaciones: RSC + SSG (Server Component estático por defecto), RSC + ISR (Server Component + revalidate), RSC + SSR (rutas dinámicas o dynamic = 'force-dynamic'). Recomendación: Server Component por defecto; Client Component ('use client') solo donde haga falta interactividad.

9 min de lectura · Publicado el: 19 dic 2025 · Actualizado el: 21 ago 2026

Comentarios

Inicia sesión con GitHub para dejar un comentario

Easton BlogEaston Blog