Saltar al contenido

La arquitectura de islas explicada

Hidratación parcial e independiente: cada componente interactivo es una isla con su propia raíz, frente al todo-o-nada de la hidratación monolítica de una SPA. El patrón que hace posible el cero-JS por defecto.

El océano de HTML y las islas

La metáfora es literal. La mayor parte de una página de contenido es un mar de HTML estático —cabeceras, párrafos, imágenes, enlaces— que no necesita JavaScript. Salpicadas en ese mar hay unas pocas regiones que sí lo necesitan: un buscador, un widget de comentarios, un selector de tema. Cada una de esas regiones es una isla: un componente interactivo, autónomo, rodeado de contenido inerte.

En una SPA no hay islas ni mar: todo es aplicación. La página es un único árbol de componentes con una sola raíz, y esa raíz gobierna hasta el último párrafo de texto. En Astro, la relación se invierte: el HTML es el continente y la interactividad son excepciones acotadas dentro de él. El patrón no lo inventó Astro —Katie Sylor-Miller lo describió antes y Jason Miller le puso nombre en 2020—, pero Astro fue el primero en construir un framework entero alrededor de la idea.

Fabrica una isla y míralo

El componente de abajo no tiene ninguna directiva: los dos componentes de framework se renderizan a HTML y se quedan inertes. Compila y comprueba que el compilador declara cero JS de cliente.

Añade client:visible al Contador y recompila: su chip aparece en la lista. Añádeselo también al Aviso y verás dos islas independientes, cada una con su especificador de framework. Quita las dos y vuelve el mensaje de cero JS.

Hidratación parcial: solo lo que hace falta

Eso que acabas de hacer es la hidratación parcial. En lugar de hidratar el documento entero, Astro hidrata únicamente los nodos marcados. Si tu página tiene un buscador y cincuenta párrafos, solo se envía y ejecuta el JavaScript del buscador. Los cincuenta párrafos jamás participan en la hidratación porque nunca fueron JavaScript: nacieron y murieron como HTML.

La consecuencia es directa sobre las métricas de la lección 1.1: el TBT se desploma porque el hilo principal apenas tiene trabajo. Y como cada isla se empaqueta por separado, el JavaScript total de la página es la suma de sus islas, no un bundle monolítico: pagas exactamente por lo que declaras.

  • Menos bytes: solo viaja el JavaScript de las islas, no un framework para toda la página.
  • Menos bloqueo: el hilo principal hidrata unos pocos nodos, no un árbol entero.
  • Mejor TTI: la página responde en cuanto arranca la primera isla, no cuando termina la última.
  • Degradación elegante: si una isla falla, el resto del documento sigue en pie.

Lo que viaja con la isla: los props serializados

Una isla no recibe sus datos ejecutando la lógica del servidor otra vez: los recibe ya calculados, serializados dentro del HTML. Esa es la cuarta zona de la frontera —el wire— y es la que más sorpresas da, porque todo lo que pases como prop a una isla se convierte en bytes que el lector descarga.

De ahí sale una regla práctica: pasa a una isla lo mínimo que necesita para funcionar. Un objeto de usuario entero, con permisos y preferencias, viaja completo aunque la isla solo use el nombre —y queda a la vista de cualquiera que abra el código fuente.

Hidratación independiente: cada isla, su propia raíz

La segunda propiedad, más sutil y más importante, es la independencia. Cada isla es una raíz de hidratación separada, con su propio fragmento de runtime y su propio ciclo de arranque. Las islas no comparten un árbol ni un scheduler común: se hidratan en paralelo y sin bloquearse entre sí.

Esto rompe el punto débil de la SPA. Allí la hidratación es todo-o-nada y de arriba abajo: hay una sola raíz, se reconstruye el árbol completo en una pasada, y si una sola parte es pesada, la interactividad de toda la página espera. En Astro, una isla pesada que tarda en hidratar no impide que una isla ligera de al lado responda de inmediato.

Cuándo se hidrata, y qué merece ser isla

La independencia también gobierna el cuándo: cada isla decide su momento con su directiva, y todas conviven sin coordinarse. client:load para lo crítico; client:visible para lo que vive abajo, vía IntersectionObserver; client:idle para lo que puede esperar a que el hilo quede libre; client:media para lo que solo existe en cierto viewport; y client:only, que omite el HTML del servidor y renderiza directo en el cliente —útil cuando el componente depende de APIs del navegador, a costa de no aportar nada al HTML inicial ni al SEO—.

En 2026 el patrón se ha extendido al servidor con las server islands, que difieren la generación de un fragmento dinámico a una petición aparte y dejan el resto de la página cacheable como estático. La misma idea —aislar lo variable de lo estable— aplicada en las dos direcciones.

No todo lo interactivo merece ser isla. Una buena isla mantiene estado propio que cambia con el tiempo, reacciona a eventos más allá de un enlace, o necesita el navegador para existir —un mapa, un canvas, un reproductor—. Si algo se resuelve con un enlace, un elemento nativo de HTML o una animación de CSS, no es una isla: es contenido con estilo.