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

«¿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.
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 buildgenera 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:
-
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
-
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».
-
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-Controlo 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:
-
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()
]);
-
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. -
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:
-
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;
-
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é.
-
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:
-
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.
-
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:
- ¿Hace falta personalización? → SSR
- ¿Con qué frecuencia cambia? → tiempo real SSR, periódico ISR, raro SSG
- ¿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?
¿Cuándo usar SSG, SSR o ISR?
¿Por qué no funciona revalidate en ISR?
¿Qué hacer si SSR carga lento al inicio?
¿Qué hacer si el build SSG tarda demasiado?
¿Se pueden mezclar distintas estrategias de renderizado?
¿Qué relación hay entre React Server Components y SSR/SSG/ISR?
9 min de lectura · Publicado el: 19 dic 2025 · Actualizado el: 21 ago 2026
Guía completa de Next.js
Si llegaste desde búsqueda, lo más rápido es ir al artículo anterior o siguiente de esta misma serie.
Anterior
Guía completa de obtención de datos en Next.js Server Components: fetch, consultas a base de datos y mejores prácticas
Guía completa para obtener datos en Server Components de Next.js: cuándo elegir fetch vs consulta directa a base de datos, patrones async/await, estrategias de caché y mejores prácticas de manejo de errores, evitando trampas comunes.
Parte 8 de 51
Siguiente
Tutorial de Next.js Server Actions: mejores prácticas para formularios y validación
Guía práctica sobre formularios con Next.js Server Actions: validación con Zod, seguridad y optimización de UX para dominar esta función que simplifica el flujo de desarrollo
Parte 10 de 51



Comentarios
Inicia sesión con GitHub para dejar un comentario