Saltar al contenido

La API prefetch() y el ClientRouter

Precargar por código con la función prefetch() del módulo astro:prefetch cuando la navegación no es un enlace, controlar su avidez con eagerness y la Speculation Rules API, saber cuándo usar la API y cuándo el atributo, y combinarla con el ClientRouter de las View Transitions para lograr navegación instantánea: red ya resuelta antes del clic y cambio de página sin recarga completa.

prefetch(): precargar cuando no hay un ancla

La función vive en el módulo virtual astro:prefetch y solo puede usarse en scripts que corren en el navegador, porque se apoya en APIs del cliente. Se importa dentro de un <script> y se llama con la ruta que quieres anticipar.

ASTRO
<button id="ir">Empezar</button><script>  import { prefetch } from 'astro:prefetch';  const boton = document.getElementById('ir');  boton?.addEventListener('pointerenter', () => {    prefetch('/onboarding/paso-1');  });</script>

Aquí el disparador no es un enlace sino la intención de pulsar un botón: al asomar el puntero, precargamos el primer paso del asistente, y cuando el clic llega y el código navega, el documento ya está en caché.

prefetch() es la herramienta para toda navegación que no nace de un <a> —botones, gestos, redirecciones tras una acción— y para primar destinos según lógica propia que ningún atributo estático podría expresar.

Hereda, además, la misma prudencia que las estrategias declarativas: prefetch() detecta el modo de ahorro de datos y las conexiones lentas, y en esos casos no precarga. Si tienes una razón de peso para forzarla —un destino crítico que justifica el gasto incluso en red pobre— existe la vía de escape explícita.

TypeScript
// Precargar incluso en ahorro de datos o conexion lentaprefetch('/checkout', { ignoreSlowConnection: true });

Usa ignoreSlowConnection con cuentagotas: cada vez que lo activas estás decidiendo por el visitante que su cuota de datos vale menos que tu milisegundo ahorrado, y esa decisión rara vez es tuya.

eagerness: sugerir al navegador cuánto anticipar

En navegadores que soportan la Speculation Rules API, prefetch() acepta un segundo grado de control: eagerness, una pista sobre con cuánta avidez debe el navegador especular con el destino. Sus valores, de más a menos agresivo, son immediate, eager, moderate y conservative, y el defecto es immediate.

Esta capacidad se apoya en el experimento clientPrerender, que eleva la precarga a prerenderizado: el navegador no solo descarga el HTML, sino que llega a construir la página en segundo plano.

ASTRO
<script>  import { prefetch } from 'astro:prefetch';  // Ruta critica en el recorrido: maxima avidez  prefetch('/getting-started');  // Ruta pesada en recursos: que el navegador modere  prefetch('/panel-con-datos', { eagerness: 'conservative' });  // Ruta que quiza no se visite: deja decidir al navegador  prefetch('/terminos', { eagerness: 'moderate' });</script>

La gracia de eagerness es que delega la decisión fina en el navegador, que conoce cosas que tu código ignora: memoria disponible, presión de CPU, cuántas especulaciones ya hay en vuelo.

Con moderate sobre un conjunto grande de enlaces, el navegador aplica una cola de tipo primero en entrar, primero en salir y sus propias heurísticas para decidir el orden y el momento, en lugar de dispararlas todas de golpe. Es la forma correcta de precargar muchos destinos sin abrumar: le das una lista y una avidez, y él la administra. Los navegadores basados en Chromium, además, imponen límites internos contra la sobreespeculación, otra red de seguridad que conviene tener presente pero no sustituye tu criterio.

Cuándo la API y cuándo el atributo

La regla para elegir entre la precarga declarativa y la programática es simple: usa el atributo siempre que puedas y la API solo cuando debas. data-astro-prefetch es estático, legible en el marcado y no cuesta un solo byte de JavaScript propio; cúbrelo todo con él mientras el destino sea un <a> visible.

Reserva prefetch() para lo que el atributo no alcanza: navegaciones que no nacen de un enlace, decisiones que dependen del contexto de red o de sesión, o el primado de un destino según una señal que solo existe en tiempo de ejecución. Y recuerda que, bajo el <ClientRouter />, buena parte de esa precarga ya ocurre sola; la API es el bisturí, no el martillo.

Componer con el ClientRouter: la latencia en dos mitades

La latencia percibida de una navegación tiene dos componentes: el tiempo de traer el documento por la red y el tiempo de pintarlo —descartar la página vieja, construir la nueva—. La precarga ataca la primera mitad.

El <ClientRouter /> de las View Transitions ataca la segunda: intercepta el clic, evita la recarga completa del navegador y sustituye el contenido con una transición suave, conservando el hilo y dando sensación de aplicación de una sola página sin serlo.

ASTRO
---// src/layouts/Base.astroimport { ClientRouter } from 'astro:transitions';---<head>  <ClientRouter /></head>

Lo notable es que ambas mitades se refuerzan, y Astro las une por defecto: en cuanto colocas el <ClientRouter />, la precarga se enciende sola con prefetchAll: true, tratando todos los enlaces de la página como candidatos.

La razón es de pura coherencia: si vas a navegar sin recargar, tiene todo el sentido que el documento ya esté en caché cuando el clic ocurra, para que la transición no tenga que esperar a la red. Puedes ajustar o desactivar ese comportamiento desde la configuración si prefieres un control más fino.

JS
// astro.config.mjs — mantener el ClientRouter pero precargar solo lo marcadoexport default defineConfig({  prefetch: {    prefetchAll: false,  },});

El resultado combinado es lo más cerca que un sitio multipágina llega de sentirse como una SPA sin pagar su precio: prefetch() —o la precarga automática— borra la espera de red antes del clic, y el <ClientRouter /> borra el parpadeo de la recarga en el clic. Dos técnicas independientes que, juntas, hacen desaparecer casi toda la latencia visible de moverse por tu sitio.