wandres.dev
MODOS DE RENDER · SSR, streaming, CSR, SSG

Islands e hidratación parcial

La hidratación de página completa envía y ejecuta JavaScript para todo el árbol, incluso para el contenido inerte que nunca reaccionará. La arquitectura de islands invierte el reparto: la página se sirve como HTML estático —un mar sin JS— y solo los fragmentos interactivos, las islas, se hidratan con su propio bundle. Esta lección explica qué problema resuelve la hidratación parcial, cómo SolidStart la ofrece tras el flag experimental islands, las piezas de control NoHydration, clientOnly e HydrationScript, y —con honestidad— el estado real del soporte en 2026: por qué la hidratación de grano fino de Solid ya es barata frente a un VDOM, por qué islands es una optimización incremental y no una necesidad, y para qué clase de sitios compensa hoy.

⏱ 17 min

Cuando una página se renderiza en el servidor y luego se hidrata, lo normal es hidratarla entera: el cliente descarga el JavaScript de todo el árbol y lo ejecuta para volver interactiva cada parte, incluso las que jamás cambiarán —un pie de página, un artículo, un encabezado—. La arquitectura de islands cuestiona ese despilfarro: propone servir la mayor parte de la página como HTML estático sin una línea de JS, y reservar la hidratación solo para los fragmentos que de verdad interactúan. Solid, por su reactividad de grano fino, es un candidato natural a este modelo; SolidStart lo ofrece, aún, como territorio experimental.

🎯 Al terminar esta lección sabrás
  • Entender qué problema resuelve la hidratación parcial frente a hidratar la página completa.
  • Conocer el flag experimental.islands de SolidStart y el rol de clientOnly y NoHydration.
  • Situar por qué la hidratación de grano fino de Solid ya abarata el problema de partida.
  • Juzgar con honestidad el estado del soporte en 2026 y para qué sitios compensa hoy.

Qué problema resuelve la hidratación parcial

Hidratar no es gratis. Aunque el HTML ya llegó pintado del servidor, el cliente debe descargar el bundle de componentes, ejecutarlo y recorrer el DOM enganchando reactividad y escuchadores. Ese trabajo escala con el tamaño del árbol, no con su interactividad: un artículo de diez mil palabras sin un solo botón cuesta hidratarse casi lo mismo que si estuviera lleno de controles, porque el framework igual lo recorre. El síntoma es un TTI tardío —la página se ve pronto pero tarda en responder— y un bundle inflado con lógica de partes que nunca la usarán.

La hidratación parcial ataca la raíz. Divide la página en dos poblaciones: el contenido estático, que se sirve como HTML puro y no recibe JavaScript alguno, y las islas interactivas, fragmentos acotados que sí se hidratan, cada uno con su bundle mínimo. El resto del documento —el mar entre las islas— queda como HTML inerte, rapidísimo y sin coste de arranque.

Y como las islas no se comunican entre sí por defecto, cada una puede cargarse e hidratarse de forma independiente —incluso perezosamente, cuando entra en el viewport o cuando el usuario la toca por primera vez—. El JavaScript no solo se reduce a lo interactivo: se puede además diferir isla por isla, de modo que la interactividad llegue escalonada según hace falta, no toda de golpe al arrancar.

La métrica que esto mueve es el TBT —el tiempo total de bloqueo— y, con él, la sensación de que la página «pesa». Una página con hidratación completa ejecuta al arrancar todo el JavaScript de su árbol en la hebra principal, y durante ese trabajo no responde a nada; con islands, la hebra solo se ocupa de las islas, y solo cuando toca. El resultado no es únicamente menos bytes descargados: es una hebra principal libre antes y por más tiempo, que es lo que el usuario percibe como una página que reacciona al instante.

Este beneficio es más agudo justo donde más duele: en móviles de gama baja, cuya CPU tarda mucho más en ejecutar JavaScript que en descargarlo. En esos dispositivos, el cuello no suele ser la red sino el procesador hidratando nodo a nodo; recortar cuánto hay que hidratar los ayuda más que a ningún equipo de gama alta, y desplaza la ganancia de islands hacia el segmento de usuarios que peor lo pasaba.

Nada de esto es exclusivo de una arquitectura con nombre; es simplemente la consecuencia de no enviar código que no hace falta. «Islands» es la etiqueta que la industria le puso al patrón, pero la idea de fondo —no hidratar lo que no interactúa— es anterior a cualquier framework y sobrevivirá a todos ellos. Conviene retener la idea más que la etiqueta, porque la etiqueta cambiará y la idea no.

flowchart TD
P[pagina renderizada en el servidor] --> H[mar de HTML estatico sin JS]
P --> I1[isla buscador]
P --> I2[isla carrito]
H --> Z[cero JavaScript enviado]
I1 --> J[solo el JS de la isla se descarga e hidrata]
I2 --> J
style H fill:#a6e3a1,color:#11111b
style J fill:#89b4fa,color:#11111b

Islands en SolidStart: el flag experimental

SolidStart expone el modo tras un flag en la configuración. Activado, cambia la política por defecto: las rutas y layouts se tratan como estáticos de servidor —render a HTML sin hidratación—, y solo los componentes marcados como islas reciben JavaScript de cliente.

// app.config.ts
import { defineConfig } from "@solidjs/start/config";

export default defineConfig({
  ssr: true,
  experimental: {
    islands: true, // hidratacion parcial: solo las islas reciben JS
  },
});

Alrededor del modo hay piezas de control finas. clientOnly envuelve un componente para que solo se renderice y viva en el cliente —útil para lo que depende de APIs del navegador—. NoHydration e Hydration, de solid-js/web, delimitan a mano regiones que no deben hidratarse frente a las que sí. Y HydrationScript, en el documento, siembra el estado que la hidratación necesita para reanudar sin volver a pedir datos.

import { clientOnly } from "@solidjs/start";
import { NoHydration } from "solid-js/web";

// Una isla: solo este componente se hidrata en el cliente.
const Buscador = clientOnly(() => import("~/islas/Buscador"));

export default function Portada() {
  return (
    <main>
      <NoHydration>
        <ArticuloLargo /> {/* HTML estatico, sin JS */}
      </NoHydration>
      <Buscador /> {/* isla interactiva */}
    </main>
  );
}
ℹ️
Islas de contenido, no de página

El grano de la decisión es el componente, no la ruta. En una misma página conviven el mar estático —cabeceras, texto, pies— y varias islas puntuales —un buscador, un carrito, un carrusel—. El objetivo es que el JavaScript que descarga el visitante sea proporcional a la interactividad que va a usar, no al tamaño del documento que va a leer.

Cómo hidrata Solid: recorrer, no reconstruir

Para juzgar islands hace falta entender qué hace exactamente la hidratación en Solid, porque su mecánica explica por qué el problema de partida ya es modesto. Cuando el cliente arranca sobre HTML de servidor, Solid no vuelve a crear nodos: recorre el DOM que ya existe y engancha en él la reactividad, cableando escuchadores y suscripciones justo donde hay expresiones que dependen de signals. El HTML se queda intacto; solo se le añade vida.

Dos piezas sostienen ese proceso. HydrationScript, colocado en el documento, siembra en la página el estado que la hidratación necesita para reanudar sin volver a pedir datos —el mismo que el streaming serializó—. Y hydrate, en lugar de render, es la función de entrada que le dice a Solid «adopta este HTML» en vez de «pinta desde cero».

import { hydrate } from "solid-js/web";

// Adopta el HTML del servidor y le engancha reactividad, sin recrear nodos.
hydrate(() => <App />, document.getElementById("app")!);

La consecuencia es que en Solid la hidratación nunca fue el desastre que es en frameworks con Virtual DOM, donde adoptar el HTML obliga a reconstruir un árbol virtual entero y compararlo con el DOM servido. Solid se salta ese paso por completo. Ese punto de partida —una hidratación ya barata, sin reconstrucción— es la clave para entender el veredicto sobre islands que viene a continuación.

Vale la pena subrayar de dónde sale ese ahorro, porque conecta con todo lo que aprendiste antes. La hidratación de Solid es barata por la misma razón que su render en cliente lo es: la reactividad de grano fino ya sabe exactamente qué trozo de DOM depende de qué signal, así que hidratar es recorrer esa correspondencia una vez y engancharla, sin diffing ni árbol intermedio. Islands no arregla un modelo roto; afina un modelo que ya era eficiente, y por eso, en Solid, es una mejora opcional y no una corrección urgente.

De ahí una consecuencia contraintuitiva: adoptar islands en Solid puede complicar más de lo que ahorra si tu página no es mayoritariamente estática. La partición en islas introduce fronteras, empaquetado por isla y las restricciones de estado que veremos enseguida; ese coste de complejidad es fijo, mientras que el ahorro es proporcional al mar estático. Solo cuando el mar es grande el balance sale a favor —y saber estimar ese balance antes de adoptar es más valioso que dominar la API—.

El estado del soporte en 2026

Aquí toca honestidad, porque el bombo suele adelantarse a la realidad. En Solid, islands sigue siendo experimental: vive tras un flag, evoluciona entre versiones y no es el camino que la documentación recomienda por defecto para una app cualquiera. Antes de adoptarlo conviene entender por qué su urgencia es menor en Solid que en otros frameworks.

La razón es estructural. La hidratación cara —el problema que islands vino a resolver— es aguda en frameworks con Virtual DOM, donde hidratar implica reconstruir un árbol virtual en memoria y compararlo con el DOM servido. Solid no tiene VDOM: su hidratación de grano fino no reconstruye nada, solo recorre el DOM existente y engancha reactividad allí donde hay dependencias. Es, de partida, mucho más barata. Islands, sobre Solid, es por tanto una optimización incremental —recortar el ya modesto coste de hidratar lo inerte— y no el rescate dramático que supone en un ecosistema con VDOM.

Esto no significa que islands no aporte nada en Solid; significa que su retorno depende mucho de la forma de tu página. En un sitio que es 95 % texto y 5 % interacción, recortar ese 95 % de hidratación —aunque cada nodo cueste poco— es un ahorro real y acumulado. En una app que es 80 % controles, apenas hay mar que dejar estático, y la complejidad de dividir en islas no se paga. El retorno de islands es, casi literalmente, proporcional a cuánto de tu página no necesita JavaScript, y por eso la decisión de adoptarlo empieza midiendo esa proporción.

📄

Sitios donde compensa hoy

Contenido mayormente estatico con islas escasas: blogs, documentacion, marketing con un widget suelto.

🧩

El grano fino ya ayuda

Sin VDOM, hidratar en Solid ya es barato; islands recorta el sobrante, no rescata de un desastre.

🔬

Territorio en movimiento

Flag experimental, APIs que pueden cambiar y trabajo en curso hacia la resumabilidad. Adoptar con cautela.

El veredicto práctico es matizado. Para una app interactiva típica, el SSR con hidratación de grano fino de las lecciones anteriores es el camino recomendado y suficiente; islands añade complejidad por una ganancia que a menudo no notarás. Para un sitio de contenido —mayormente texto, islas contadas— islands puede recortar de veras el JavaScript enviado y merece la prueba, asumiendo que pisas terreno experimental.

Ese «asumiendo que pisas terreno experimental» no es una fórmula de cortesía. Un flag experimental puede cambiar de forma entre versiones, tener aristas sin pulir en el enrutado o la carga, y menos material de referencia cuando algo falla. Adoptarlo es una apuesta razonable para un proyecto que puede permitirse seguir de cerca la evolución del framework; es una imprudencia para uno que necesita cimientos estables y aburridos. Saber en cuál de los dos estás es parte de la decisión, y no la parte técnica. Y en el horizonte asoma la resumabilidad, la idea de reanudar en el cliente el trabajo del servidor sin re-ejecutar la hidratación; es investigación activa, no una casilla que marcar hoy.

Un límite conceptual conviene nombrarlo, porque no es un defecto sino la esencia del modelo: como cada isla es una raíz de hidratación independiente, compartir estado reactivo entre islas no es trivial. Dos islas que deban coordinarse no pueden pasarse un signal como dos componentes del mismo árbol; necesitan un canal externo —un store global, eventos, la URL—. Cuanto más quieran hablar entre sí tus islas, menos natural resulta la arquitectura, y más se acerca el punto en que una app plenamente hidratada era la respuesta correcta desde el principio.

Esa tensión —islas que quieren coordinarse— es, además, el mejor termómetro para saber si tu página encaja en el modelo. Si cada isla es un widget autónomo que no necesita a las demás, islands fluye; si tu interfaz es un organismo cuyas partes se coordinan sin cesar, estás peleando contra la arquitectura, y la señal aparece antes incluso de escribir la primera línea. Escuchar ese termómetro te ahorra adoptar islands para arrepentirte a mitad de la implementación.

Resumido sin rodeos: si tu app es sobre todo interactiva, usa SSR con hidratación de grano fino y no toques islands todavía; si tu sitio es sobre todo contenido con interacción puntual y aislada, prueba islands sabiendo que pisas terreno experimental y que sus APIs pueden moverse; y en ambos casos, mide antes de complicar, porque el peor motivo para adoptar una arquitectura es que suene moderna.

La hidratación parcial es un problema de proporción, no de velocidad

La forma correcta de pensar islands no es «hidratar más rápido» sino «hidratar solo lo que lo merece», y la diferencia entre ambas framings lo cambia todo. El coste de la hidratación no depende de cuán interactiva sea tu página, sino de cuánto árbol tenga: el framework recorre lo que le des, reactivo o no. Islands rompe esa proporcionalidad tóxica —coste atado al tamaño— y la sustituye por la sana —coste atado a la interactividad—, de modo que un documento gigante con tres botones pague por tres botones y no por el documento. Ahí está su elegancia conceptual y también el porqué de que en Solid sea menos apremiante que en otros lados: cuando tu hidratación ya es de grano fino y no reconstruye ningún árbol virtual, la proporción de partida ya es benigna, y recortarla más es afinar, no salvar. Esto deja una lección que trasciende a la API concreta y a su estado experimental. Cada modo de renderizado que has visto en este nivel es, en última instancia, una respuesta a la misma pregunta económica: ¿qué trabajo ejecutamos, dónde y cuándo, para que el usuario pague lo mínimo por lo que de verdad necesita? El streaming solapa el trabajo en el tiempo; el SSG lo adelanta al build; el CSR lo traslada entero al cliente; e islands lo acota en el espacio, delimitando qué regiones del árbol merecen el gasto de volverse vivas. Ninguno es universalmente mejor; cada uno mueve el coste a un eje distinto —tiempo, momento, lugar, extensión—. Cuando internalizas que renderizar es administrar ese coste a lo largo de varios ejes a la vez, dejas de coleccionar modos como recetas sueltas y empiezas a leerlos como lo que son: variaciones de una misma pregunta, cada una óptima bajo una restricción, y todas a tu disposición para combinarlas ruta por ruta.

⚔️ Explora la hidratación parcial con criterio
  1. En una app SSR normal, mide el JavaScript descargado y el TTI de una página larga con poca interacción; anota cuánto de ese JS sirve a partes inertes.
  2. Activa experimental.islands y convierte un widget interactivo en isla con clientOnly; comprueba que el resto de la página se sirve como HTML sin su JS.
  3. Envuelve un bloque de contenido puro en NoHydration y verifica en el inspector que no recibe reactividad ni escuchadores.
  4. Argumenta, con el hecho de que Solid no tiene VDOM, por qué islands es aquí una optimización incremental y no un rescate como en frameworks con Virtual DOM.
  5. Decide para tres proyectos —un blog, un editor, una tienda— si islands compensa hoy o si el SSR de grano fino basta, y justifica cada veredicto por su proporción de estático a interactivo.