From n00b to ZeroCool / Profesionalización
SPA, SSR, SSG e ISR: la sopa de siglas que define si tu sitio vuela o se arrastra
Aprende SPA, SSR, SSG e ISR con ejemplos reales y un árbol de decisión para escoger según SEO, performance, costos y operación.
Lo que vale la pena leer aquí
Tu PM te escribe a las 6:48 pm: “Oye, el landing tiene que cargar rápido porque la campaña sale mañana y el SEO anda flojo”. Tú volteas a ver tu laptop ya guerita del teclado gastado, el build tarda como si estuviera minando crypto, y alguien del equipo suelta la frase comodín:
Tu PM te escribe a las 6:48 pm: “Oye, el landing tiene que cargar rápido porque la campaña sale mañana y el SEO anda flojo”. Tú volteas a ver tu laptop ya guerita del teclado gastado, el build tarda como si estuviera minando crypto, y alguien del equipo suelta la frase comodín:
“Pues… SSR, ¿no?”
Ahí arranca la sopa de siglas: SPA, SSR, SSG, ISR. Todas suenan a “sí, con eso se arregla”, hasta que te toca hacer deploy tarde, cachar un bug raro de caché, y explicarle a negocio por qué el contenido no se actualiza “en tiempo real” si lo “dejamos estático”.
La neta: no es religión, es logística de HTML. Qué generas, cuándo, y quién paga la cuenta cuando algo se rompe en production.
Qué te vas a llevar
- Qué significa SPA vs SSR vs SSG vs ISR en términos de qué HTML llega y cuándo se genera.
- Cómo se pelean con SEO, performance real, costo/infra y operación (cachés, invalidaciones, deploys).
- Un árbol de decisión para elegir por página (no por framework).
- Una estrategia híbrida típica que aguanta el jale (con Next.js como referencia mental, pero aplica a otros stacks).
La pregunta que sí importa
Estas siglas son estrategias para servir páginas. La pregunta real es:
¿Cuándo existe el HTML y quién lo genera: el server, el build o el navegador?
Y la que casi nadie hace hasta que truena production:
¿Quién se va a encargar de que el contenido sea “fresco”: tú, el caché, o una combinación peligrosa de ambos?
Dos escenas bien comunes:
-
Campaña con presupuesto (Meta/Google): si el landing se tarda, el CPC se siente como mordida. “En mi wifi jala” no cuenta; en 4G con señal chueca en el metro, se cae el teatro.
-
E-commerce con catálogo grande: “quiero todo indexado”, “todo rápido”, “y que el precio se actualice cuando lo cambie el ERP”. Ajá… y también sin subir el costo de infra.
Con eso en mente, vámonos por partes.
Guía principal: SPA/SSR/SSG/ISR sin llorar
1) SPA (Single Page Application): render en el cliente
Qué pasa: el server manda un HTML básico (casi vacío) + JavaScript. El navegador ejecuta JS, arma la UI, hace fetch de datos y renderiza.
Cómo se siente:
- Primera carga pesada si tu bundle está gordo.
- Navegación interna rápida.
- SEO “depende”: Google a veces ejecuta JS, pero no siempre como tú quieres (y otros bots ni de broma).
Cuándo sí conviene:
- Apps internas (dashboards, CRMs, tickets).
- Producto donde el usuario sí o sí inicia sesión.
- Flujos muy interactivos donde el contenido no necesita indexarse.
Tradeoff real: si tu objetivo es adquisición orgánica, una SPA sin prerender es como abrir un local con la cortina abajo y esperar que entre gente.
Ejemplo rápido:
- Panel de soporte: SPA, sin miedo.
- Blog/landing principal: mala idea si te vas full client sin prerender.
2) SSR (Server-Side Rendering): HTML en cada request
Qué pasa: cada request genera HTML en el server (o en edge). Luego “hidratas” en el cliente para que haya interactividad.
Cómo se siente:
- Mejor arranque percibido si está bien cacheado y no haces cosas raras.
- SEO suele mejorar porque el HTML ya trae contenido.
- Costo por request: el server trabaja cada vez.
Cuándo sí conviene:
- Contenido dinámico por usuario/permisos.
- Páginas donde la frescura es crítica (precio/stock, feeds personalizados).
- Cuando no puedes pre-generar por combinaciones infinitas.
Tradeoff real:
- SSR sin caché = “bonito en dev, caro y lento en production”.
- SSR pegándole a una API lenta = tu server se vuelve el cuello de botella.
3) SSG (Static Site Generation): HTML en build
Qué pasa: generas HTML en build time. Sirves archivos estáticos por CDN.
Cómo se siente:
- Rápido, como caché calentito.
- Barato de servir.
- SEO feliz.
Cuándo sí conviene:
- Marketing, docs, blogs, páginas casi inmutables.
- Catálogos que cambian poco o donde toleras un delay.
Tradeoff real: si tienes miles de páginas y cambian seguido, los builds se vuelven eternos. Y sale el clásico: “ya lo cambié en el CMS pero el sitio no”.
4) ISR (Incremental Static Regeneration): estático con refresh controlado
Qué pasa: sirves estático, pero ciertas páginas se regeneran en background según una política (por tiempo o bajo demanda con revalidación).
Cómo se siente:
- Performance de estático casi siempre.
- Actualizaciones sin rebuild completo.
- Complejidad extra: cachés, invalidación, contenido stale y comportamientos raros en edge.
Cuándo sí conviene:
- Catálogos y blogs con contenido frecuente.
- Landings que cambian cada semana.
- Sitios grandes donde SSG total ya no escala.
Tradeoff real: ISR te ahorra talacha de builds, pero te cobra en operación: saber qué se revalida, cuándo, y por qué alguien vio “lo de hace 10 minutos”.
Árbol de decisión (rápido pero usable)
Hazte estas preguntas por tipo de página:
- ¿Necesita SEO fuerte?
- No → SPA (o SSR si tu app lo exige)
- Sí → SSR/SSG/ISR
- ¿Cambia seguido el contenido?
- No / raro → SSG
- Sí, pero tolero retraso (minutos) → ISR
- Sí, y debe estar fresco siempre → SSR
- ¿Es personalizado por usuario?
- Sí → SSR (o SPA + API, pero SEO se complica)
- No → SSG/ISR
- ¿Tu build ya se está muriendo?
- Sí → ISR o SSR selectivo; SSG total deja de escalar.
La decisión madura casi siempre es híbrida: no todo el sitio tiene que renderizar igual.
Estrategia híbrida que sí sobrevive a producción
Piensa en Next.js para aterrizar ideas (pero esto se traduce igual a Nuxt, SvelteKit, Astro, etc.).
Paso 1: clasifica rutas como si fueras SRE 10 minutos
Arma una tablita (tal cual en tu pull request) con algo así:
/home (SEO, cambia poco)/blog/[slug](SEO, cambia seguido)/producto/[id](SEO, cambia por precio/stock)/checkout(no SEO, personal)/dashboard(no SEO, personal)
Si no lo puedes explicar en una tabla, probablemente tu setup ya está demasiado enredado.
Paso 2: asigna estrategia por ruta (sin casarte)
Un combo típico que funciona:
- Home + marketing → SSG
- Blog posts → ISR (revalidación cada X)
- Producto → ISR si toleras minutos de desfase; SSR si no
- Checkout/Dashboard → SPA (o SSR solo por auth, depende)
Ojo: esto no es “lo correcto universal”, es “lo que te evita un rollback a medianoche”.
Paso 3: mide lo que duele (no lo que se ve bonito en tu máquina)
Métricas que sí cambian decisiones:
- TTFB (SSR sin caché se delata aquí)
- LCP (HTML temprano ayuda, pero imágenes y fuentes también)
- JS bundle size (hidratar de más te mata igual con SSR/SSG)
- Cache hit ratio (cuando metes CDN/edge)
Regla de barrio: prueba en 4G simulado + CPU throttling. Tu laptop gamer no representa al usuario con Android gama media.
Paso 4: “hidrata solo lo que respira”
SSR/SSG/ISR te dan HTML, pero si hidratas toda la página como si fuera app, pagas en JS.
- Componentes interactivos: sí, hidrata.
- Texto, layout, contenido: déjalo quieto.
Traducción práctica:
- Separar Server/Client components (si aplica en tu stack)
- Evitar estados globales donde no hacen falta
- Lazy-load de widgets pesados (chat, mapa, carruseles)
Paso 5: define tu política de frescura (y déjala escrita)
Esto evita el “¿por qué no se actualiza?” cuando ya te ibas a dormir.
- Blog: revalida cada 10–30 min
- Producto: revalida cada 1–5 min, o on-demand cuando cambie precio
- Home: revalida cada hora o por deploy
En Next (ejemplo conceptual):
// ISR por tiempo (conceptual)
export const revalidate = 300; // 5 min
On-demand revalidation (conceptual):
// endpoint protegido que revalida cuando el CMS publica
// (conceptual; varía por versión/framework)
export async function POST(req) {
// validar firma/token del CMS
// revalidatePath('/blog/mi-post')
return Response.json({ ok: true });
}
El snippet es lo de menos. Lo clave es tener un trigger (webhook del CMS/ERP) y un contrato de frescura que negocio entienda.

Screenshots sugeridos
- DevTools Performance/Lighthouse mostrando LCP/TTFB antes y después (misma página en SSR vs SSG).
- Diagrama simple de flujo: Request → CDN cache → server render vs static file.
- Captura de logs/monitoring con picos de latency cuando SSR pega a API lenta.
- Pantalla de tu CMS/webhook o endpoint de revalidación (con datos sensibles ocultos).
Errores comunes (y cómo salir vivo)
Error 1: “Hagamos SSR para todo y ya”
Síntoma: al principio “se siente rápido”, llega tráfico y el server se ahoga.
Salida: SSR selectivo + cache/CDN + no pegarle a la DB en cada request. Si no es personalizado, probablemente no necesita SSR.
Error 2: SSG para catálogo enorme y builds interminables
Síntoma: el deploy tarda 25–40 min, el CI se llena, publicar es peregrinación.
Salida: ISR para catálogo y SSG solo para lo realmente estable.
Error 3: “Tenemos ISR” pero sin estrategia de invalidación
Síntoma: cambian precio en el admin y el sitio tarda; te cae el “¿ya quedó?”
Salida: define revalidate por tipo de página + on-demand revalidation cuando el origen cambie.
Error 4: SEO raro porque la página depende de JS
Síntoma: tú ves contenido, pero Search Console muestra titles/metas inconsistentes o snippets vacíos.
Salida: asegura HTML con contenido relevante (SSR/SSG/ISR) y metas por ruta. No dependas de JS para title/description.
Error 5: hidratas todo y matas performance
Síntoma: TTFB bien, pero LCP/INP mal. Mucho JS, mucha re-render.
Salida: baja JS, divide bundles, hidrata solo lo necesario, lazy-load lo no crítico.

Checklist final (para decidir sin volarte la noche)
- ¿Esta página necesita SEO? (sí/no)
- ¿El contenido es público o personalizado?
- ¿Con qué frecuencia cambia y cuánto retraso tolera negocio?
- ¿Qué tan caro es generar la página (API/DB/terceros)?
- ¿Tengo cache/CDN y sé si pega hit o miss?
- ¿Mi build escala o ya está tronando?
- ¿Qué tanto JS estoy mandando? (hidratar solo lo necesario)
- ¿Tengo monitoreo de TTFB y LCP en producción?
FAQ
1) ¿SSR siempre es mejor para SEO?
Suele ayudar porque entregas HTML con contenido desde el server, pero SEO también depende de metas, canonical, estructura, performance e indexabilidad. SSR lento o con contenido incompleto también pierde.
2) ¿SSG es “gratis” en performance?
Servir estático por CDN es rapidísimo, pero lo puedes arruinar con imágenes pesadas, JS excesivo o fuentes mal cargadas. SSG te da base, no inmunidad.
3) ¿ISR significa que ya no necesito rebuild?
Vas a necesitar deploy para cambios de layout, dependencias o rutas nuevas. ISR te evita rebuilds completos por cambios de contenido. Es “menos rebuild”, no “cero deploys”.
4) ¿Puedo mezclar estrategias en el mismo proyecto?
Sí, y normalmente es lo correcto: home en SSG, blog en ISR, producto en ISR/SSR, dashboard en SPA. Elegir por ruta te da performance y control.
5) ¿Qué elijo si tengo deadline y no sé?
Si es landing/blog y te urge SEO + velocidad: SSG. Si cambia seguido: ISR con un revalidate razonable. Evita SSR global si no tienes caché y observabilidad listos.
Siguiente episodio: teaser
La sopa de siglas no termina: toca hablar de hidratación, islands y Server Components.
Porque sí: puedes tener SSR/SSG y aun así mandar demasiado JS… y eso también se paga.
Idea para cerrar bien este post: toma una sola práctica de aquí y conviértela en algo que tu equipo pueda aplicar hoy.
Cuando un artículo aterriza en decisiones reales, deja de ser contenido y se vuelve ventaja.


