Saltar al contenido

Estrategias: static-first, SSR selectivo y server islands

Con el eje entendido y su coste medido, queda decidir dónde poner cada página real. Tres estrategias ordenan la decisión —static-first como disciplina, SSR selectivo para lo que lo exige y server islands para lo casi estático con un punto vivo— gobernadas por un criterio: el tipo de página. Cómo elegir y por qué la granularidad de la decisión no deja de encogerse.

Static-first: lo barato como punto de partida

La primera estrategia no es una técnica sino una postura por defecto: todo es estático hasta que se demuestre que no puede serlo. Se mantiene output: 'static', se hornea cuanto se pueda, y cada ruta que aspire a bajo demanda debe justificar su gasto. La razón es la que este nivel viene repitiendo: lo estático es casi gratis de operar, se sirve instantáneo desde el edge, resiste una avalancha de tráfico sin despeinarse y no tiene servidor que pueda caerse.

Hay un segundo argumento, menos citado y muy poderoso: la superficie de ataque. Un fichero HTML servido desde una CDN no tiene lógica que explotar, ni conexión a base de datos que inyectar, ni proceso que tumbar. Cada página que dejas estática es una página que sale, además de rápida y barata, más segura y más resistente por construcción. Lo dinámico es una capacidad valiosa, pero también una responsabilidad: un servidor que mantener, parchear y vigilar.

Puesto en positivo, cada ruta que consigues hornear te regala de golpe cuatro propiedades que lo dinámico tendría que ganarse una a una:

  • Velocidad: se sirve desde el nodo del edge más cercano, sin cómputo ni espera a ninguna fuente.
  • Escala: el mismo fichero atiende un pico de tráfico enorme sin despertar servidor alguno.
  • Resistencia: no hay proceso que se caiga; mientras la CDN viva, la página responde.
  • Seguridad: sin lógica en vivo, no hay casi nada que un atacante pueda ejecutar.

Static-first no es dogmatismo anti-dinámico; es orden de prioridad. Empiezas por la respuesta barata y solo pagas por la cara cuando la naturaleza de la página lo impone —cuando lee la petición, cuando personaliza, cuando exige frescura al segundo—. Invertir ese orden, arrancar en output: 'server' y congelar lo que se pueda, es legítimo para una aplicación que es dinámica de raíz, pero para la mayoría de los sitios —contenido en su esencia— static-first minimiza las excepciones y, con ellas, el coste y la superficie de fallo.

SSR selectivo y server islands

Cuando una ruta entera depende de la petición, la marcas bajo demanda y ya está: eso es el SSR selectivo. Un buscador que lee la consulta, un panel de cuenta que valida una sesión, un carrito que refleja un estado vivo. Son páginas cuya sustancia es la petición, y para ellas el bajo demanda no es un lujo sino la única forma correcta.

ASTRO
---// src/pages/cuenta.astro  -> toda la pagina depende de la sesionexport const prerender = false;const sesion = Astro.cookies.get('sesion')?.value;const usuario = sesion ? await validarSesion(sesion) : null;if (!usuario) return Astro.redirect('/entrar');---<h1>Hola, {usuario.nombre}</h1>

La clave del SSR selectivo es que sea selectivo: no arrastres al modo servidor páginas vecinas que no lo necesitan solo porque comparten diseño. Cada ruta lleva su propia bandera, y la de al lado —la portada, el aviso legal— puede seguir horneada aunque esta viva bajo demanda. Marcar de más es el desperdicio más común, y el que las server islands vienen a evitar.

Pero hay un caso intermedio muy común que ninguna de las dos posturas anteriores resuelve bien: una página casi toda estática con un solo trozo dinámico. Un artículo de blog cacheable con un saludo personalizado en la esquina; una ficha de producto horneada con un stock en vivo. Marcar la página entera como bajo demanda por ese trozo sería tirar a la basura la cacheabilidad de todo lo demás. Para eso están las server islands: marcas solo ese componente con la directiva server:defer, y Astro sirve la página como HTML estático cacheable con un hueco donde la isla se renderiza aparte, en el servidor, y se inyecta al llegar.

ASTRO
---// La pagina se hornea y se cachea entera...import Articulo from '../components/Articulo.astro';import SaludoUsuario from '../components/SaludoUsuario.astro';---<Articulo /><!-- ...salvo esta isla, que se renderiza bajo demanda y se inyecta --><SaludoUsuario server:defer>  <span slot="fallback">Hola</span></SaludoUsuario>

La isla en sí es un componente corriente que lee lo que necesita de la petición; lo único especial es la directiva que le pusiste al usarlo.

ASTRO
---// src/components/SaludoUsuario.astro -> se renderiza en el servidor, por peticionconst usuario = await usuarioDeLaSesion(Astro.cookies);---<span>Hola, {usuario?.nombre ?? 'invitado'}</span>

Bajo el capó, la server island es un mecanismo simple y elegante. Astro hornea la página con un marcador en el lugar de la isla y un contenido de reserva visible —el slot de fallback—; el navegador recibe ese HTML estático al instante y, por detrás, pide solo el trozo diferido a una ruta especial que lo renderiza en el servidor y lo devuelve para ocupar el hueco. El resultado invierte la relación entre lo estático y lo dinámico: antes, un solo trozo vivo obligaba a servir viva la página entera; ahora la carcasa sigue siendo estática y cacheable, y es únicamente el fragmento el que se difiere. Cada parte se cachea según su propia naturaleza —la carcasa para siempre, la isla nunca o poco—, algo imposible cuando la unidad de decisión era la página completa.

Elegir por tipo de página

Las tres estrategias convergen en una sola pregunta operativa que se resuelve mirando qué clase de página tienes delante. La mayoría cae con nitidez en uno de tres cajones.

  • Estática pura: landings, artículos, documentación, páginas institucionales. Contenido igual para todos y estable. Se hornean y punto.
  • Bajo demanda entera: buscadores, paneles, carritos, checkout. Su sustancia es la petición o la sesión; el SSR selectivo es su sitio.
  • Estática con isla: una página mayormente cacheable con un fragmento personalizado o en vivo. Estática de base con una server island para el trozo dinámico.

Una tienda ilustra los tres a la vez y enseña a repartir. La portada y las páginas de categoría son contenido estable: estáticas. La ficha de un producto es casi toda estática —descripción, fotos, especificaciones— con un dato vivo, el stock: candidata perfecta a server island, carcasa horneada más una isla para las existencias. Y el carrito o el checkout dependen enteramente de la sesión del comprador: bajo demanda sin discusión. Un mismo sitio, las tres estrategias, cada página en el cajón que le dicta su naturaleza y no una etiqueta global impuesta sobre todas.

Visto así, las tres estrategias no compiten: se encajan. Static-first fija el suelo —todo horneado salvo prueba en contra—; el SSR selectivo levanta las pocas rutas que son aplicación entera; y las server islands recortan huecos vivos en las páginas que son casi documento. Un sitio bien pensado usa las tres a la vez, cada una en su escala, y el resultado es un reparto donde ninguna pieza paga más coste del que su naturaleza exige. No hay que elegir una estrategia para el proyecto: hay que aplicar la que corresponde a cada página, y a veces a cada fragmento.

Con esto cierras el nivel. Sabes qué es el eje de render, cómo fijarlo por página con prerender, qué te ofrece el objeto Astro bajo demanda, cómo se paga cada momento y con qué estrategia repartir tus páginas. Lo que queda por delante —imágenes, i18n, seguridad, despliegue— se construye sobre estas decisiones, porque el momento de render es el cimiento sobre el que se apoya todo lo demás de un sitio en producción.