wandres.dev
PREFETCH Y NAVEGACIÓN · estrategias de prefetch

Presupuesto de rendimiento: LCP, INP y Save-Data

Situar la precarga dentro de un presupuesto de rendimiento: cómo compite con el LCP de la página actual, qué relación tiene con el INP cuando se eleva a prerenderizado, en qué orden priorizar el gasto, y por qué respetar el modo de ahorro de datos y las conexiones lentas no es cortesía sino diseño.

⏱ 16 min

La precarga no es gratis, y tratarla como si lo fuera es el error que convierte una optimización en un lastre. Cada byte que anticipas para la página siguiente compite —por la red, por la CPU, por la batería— con la página que el visitante mira ahora. Un ingeniero maduro no pregunta si la precarga es buena o mala, sino cuánto presupuesto tiene y en qué lo gasta. Esta lección enmarca prefetch dentro de un presupuesto de rendimiento: su relación con las métricas que la industria mide, el orden en que conviene gastarlo, y su respeto por la red del visitante.

🎯 Al terminar esta lección sabrás
  • Situar la precarga dentro de un presupuesto de rendimiento acotado.
  • Relacionar la precarga con el LCP de la página actual y de la siguiente.
  • Entender su efecto sobre el INP cuando se eleva a prerenderizado.
  • Priorizar el gasto y respetar Save-Data y las conexiones lentas.

Precarga contra LCP: la página de ahora frente a la de después

El LCP —Largest Contentful Paint— mide cuándo aparece el elemento visible más grande de una página; es la métrica que resume cuánto tarda en cargar. La precarga tiene con el LCP una relación doble, y confundir sus dos caras es la raíz de casi todos los errores.

Para la página siguiente, la precarga es una bendición. Si su documento y sus recursos ya están en caché cuando el visitante navega, su LCP se desploma, porque no hay que esperar a la red. Ese es el beneficio que persigues, y es real.

Para la página actual, en cambio, la precarga es un competidor. Cada descarga anticipada disputa ancho de banda a los recursos que el visitante necesita ver ya. Por eso Astro emite la precarga con prioridad baja mediante <link rel="prefetch">, para que el navegador la posponga tras lo crítico.

En una conexión holgada, esa prioridad baja basta para que la precarga no dañe el LCP presente: el navegador la mete en los huecos ociosos del caño. En una conexión estrecha, donde todo compite por un tubo fino, precargar de más sí puede retrasar el LCP de la página que se está mirando. Has hipotecado el presente por un futuro que quizá no llegue.

Precarga e INP: cuando anticipar cuesta CPU

El INP —Interaction to Next Paint— mide la latencia entre que el visitante interactúa y la pantalla responde; es la métrica de cuánto responde una página. La precarga clásica, que solo descarga un documento, es casi pura red y apenas toca el hilo principal, así que su efecto sobre el INP de la página actual es mínimo.

La historia cambia con el prerenderizado. Cuando elevas la precarga a prerender —vía clientPrerender y la Speculation Rules API—, el navegador no solo trae el HTML: construye la página en segundo plano, ejecuta sus scripts, monta sus islas.

Eso ya no es solo red, es CPU, y esa CPU compite con la capacidad de la página actual de responder a las interacciones. El coste de red de un documento se paga en un caño que suele tener holgura; el coste de CPU de un prerender se paga en el único hilo por el que también pasan los eventos del visitante.

Prerenderizar una página pesada mientras el visitante intenta escribir en un campo puede encarecer su INP de forma perceptible. La regla que se deduce es limpia: cuanto más caro es el destino, más conservadora debe ser su anticipación. De ahí que eagerness: 'conservative' exista justo para las rutas intensivas en recursos.

Prioridad: en qué orden se gasta el presupuesto

Un presupuesto no solo tiene un techo, tiene un orden. Cuando los recursos escasean, lo primero que se financia debe ser lo de mayor retorno.

En precarga, eso significa reservar la anticipación temprana para el puñado de destinos que gobiernan de verdad el recorrido del visitante, y dejar el resto en espera o sin precargar.

Ese orden puede expresarse en la configuración, eligiendo una defaultStrategy tacaña como suelo común y subiendo a estrategias agresivas solo en los enlaces clave.

// astro.config.mjs — suelo conservador, lujo puntual
export default defineConfig({
  prefetch: {
    prefetchAll: true,
    defaultStrategy: 'tap',
  },
});

O puede expresarse por código, cuando la decisión depende del contexto de red que solo se conoce en el cliente. La API programática, leída junto a navigator.connection, deja modular la apuesta enlace por enlace y momento a momento.

// Financiar primero lo critico; condicionar lo accesorio a que haya margen
import { prefetch } from 'astro:prefetch';

const conexion = navigator.connection;
const redHolgada = !conexion?.saveData && conexion?.effectiveType === '4g';

prefetch('/checkout');                     // critico: siempre
if (redHolgada) prefetch('/recomendados'); // accesorio: solo si sobra red

Financiar primero lo esencial y condicionar lo accesorio a que haya margen es la traducción literal de un presupuesto a código. No precargas todo lo que puedes, sino todo lo que el retorno y la red del visitante justifican, y en ese orden.

Save-Data y la red del visitante: diseño, no cortesía

Los navegadores exponen señales sobre la red y las preferencias del visitante: la cabecera Save-Data, el indicador navigator.connection.saveData para el modo de ahorro, y effectiveType para estimar la calidad de la conexión. Astro las respeta de fábrica, y su manera de hacerlo es más fina que un simple encendido y apagado.

Esas señales no son exclusivas del cliente: el servidor también recibe la cabecera Save-Data en la petición, lo que te permite adaptar incluso el HTML que emites —no solo la precarga— para quien pide ahorro.

---
// El servidor tambien ve la senal de ahorro en la peticion
const ahorro = Astro.request.headers.get('Save-Data') === 'on';
---

Con las estrategias declarativas, si Astro detecta ahorro de datos o conexión lenta, degrada cualquier estrategia a tap: no deja de precargar del todo, pero retrasa la apuesta hasta el instante casi seguro previo al clic, que es el más barato. Con la API programática, prefetch() directamente no precarga en esas condiciones, salvo que fuerces ignoreSlowConnection. Dos comportamientos, una misma filosofía: cuando el visitante señala que su red es escasa o cara, la anticipación se encoge sola.

Respetar esas señales no es una cortesía opcional, es parte del diseño de rendimiento. El visitante en modo de ahorro suele ser el que paga sus megabytes, el de la conexión intermitente en un tren, el del dispositivo modesto en un mercado emergente.

Precargar agresivamente sobre él invierte el sentido de la optimización: le quitas datos y batería para ahorrarle una espera que quizá ni valoraba. La velocidad que se construye ignorando al visitante más frágil no es velocidad, es privilegio disfrazado de ingeniería.

flowchart TD
B[presupuesto de rendimiento] --> A[precarga en curso]
A --> LCPa[compite con el LCP actual por la red]
A --> LCPs[mejora el LCP de la pagina siguiente]
A --> INP[si hay prerender compite por la CPU]
LCPa --> G[gasto justificado solo si acierta]
LCPs --> G
INP --> G
style B fill:#89b4fa,color:#11111b
style LCPs fill:#a6e3a1,color:#11111b
style INP fill:#f38ba8,color:#11111b
style G fill:#f9e2af,color:#11111b
ℹ️
La prioridad baja es lo que hace segura la precarga del LCP actual

Que Astro emita la precarga como <link rel="prefetch"> con prioridad baja no es un detalle: es la salvaguarda que evita que anticipar la página siguiente dañe el LCP de la actual. El planificador del navegador atiende primero los recursos críticos —el HTML, el CSS que bloquea, la imagen del LCP— y solo mete la precarga en los huecos que quedan. Por eso, en una red holgada, puedes precargar sin miedo; y por eso, en una red saturada donde no quedan huecos, hasta la prioridad baja acaba compitiendo. La prioridad ordena la cola, pero no crea ancho de banda que no existe.

📝
La precarga es una transferencia de coste entre dos páginas

Vale la pena decirlo sin rodeos: precargar traslada trabajo de la página siguiente a la actual. Ese traslado sale a cuenta cuando la página actual tiene ancho de banda ocioso y la siguiente se visita de verdad; sale caro cuando la actual va justa de red o la siguiente no se abre. No hay una respuesta universal, solo un balance que cambia con la red, el dispositivo y la probabilidad del acierto. Presupuestar es, precisamente, tomar en serio ese balance en vez de suponer que anticipar siempre suma.

⚠️
ignoreSlowConnection revoca una protección; no lo hagas por reflejo

La opción ignoreSlowConnection fuerza la precarga aun en ahorro de datos o red lenta. Existe para el caso legítimo y raro —un destino tan crítico en el recorrido que justifica el gasto incluso en condiciones pobres— pero usarla por defecto anula la salvaguarda que protege justo a quien menos puede permitirse el despilfarro. Antes de escribirla, pregúntate si estás decidiendo por el visitante que su cuota de datos importa menos que tu milisegundo. Si la respuesta no es un sí rotundo y argumentado, no la escribas.

💡
Prioriza como priorizas el gasto: por retorno esperado

Un presupuesto se administra ordenando gastos por retorno. Aplica lo mismo a la precarga: reserva la anticipación temprana y agresiva —viewport, load, eagerness alto— para el puñado de destinos con alta probabilidad y alto valor en el recorrido: el siguiente paso de un asistente, el botón principal de una landing, el artículo destacado. Deja el resto en tap o sin precargar. La mayoría de tu velocidad percibida vendrá de acertar en unos pocos enlaces clave, no de precargarlos todos por igual.

🎯

LCP siguiente

El premio: la pagina de destino ya en cache pinta su contenido principal sin esperar a la red.

⚖️

LCP actual

El riesgo: en redes estrechas, precargar de mas roba ancho de banda a lo que se mira ahora.

🧠

INP y prerender

Prerenderizar ejecuta la pagina siguiente: gasta CPU y puede encarecer la respuesta de la actual.

📉

Save-Data

Ahorro de datos y red lenta encogen la precarga sola. Respetarlo es parte del diseno, no un extra.

Un presupuesto es la confesión de que todo recurso es finito y compartido

La palabra presupuesto trae consigo la única verdad que la optimización ingenua se niega a aceptar: los recursos son finitos y están compartidos. Hay un solo caño de red, un solo hilo principal, una sola batería, y todo lo que hace tu página —incluida la precarga de la siguiente— bebe del mismo depósito. La mentalidad inmadura ve cada técnica en aislamiento: la precarga acelera, luego precarga más. La madura ve el sistema completo: precargar la página de después gasta un recurso que la página de ahora necesita, y el saldo puede ser positivo o negativo según la red, el dispositivo y la probabilidad del acierto. Por eso un presupuesto de rendimiento no es una hoja de cálculo que rellenas al final, sino una forma de pensar que aplicas desde el principio: cada mejora tiene un coste que alguien paga, y tu trabajo es que el retorno supere a ese coste para el visitante real, no para el ideal de fibra y portátil nuevo con el que desarrollas. Las Core Web Vitals —LCP, INP— son el intento de la industria de poner número a esa contabilidad, de convertir la vaga sensación de rápido en algo medible y presupuestable. Pero el número es el mapa, no el territorio: el territorio es una persona con un teléfono viejo en una red que se paga por megabyte, y la pregunta última no es cuánto baja mi LCP sino a costa de qué, y de quién. Un ingeniero que interioriza esto deja de perseguir métricas y empieza a administrar un bien común escaso. Y descubre que la restricción más elegante no es la que le imponen las herramientas, sino la que se impone él mismo: gastar solo cuando el retorno es claro, y respetar siempre la señal de quien dice que no puede permitírselo.

⚔️ Presupuesta tu precarga
  1. Con la red limitada a un perfil lento en las herramientas del navegador, carga una página con prefetchAll y load, y observa si el LCP de la página actual se resiente frente a la misma página sin precarga.
  2. Activa el modo de ahorro de datos y confirma que las estrategias declarativas se degradan a tap y que prefetch() deja de disparar descargas.
  3. Escribe la comprobación de navigator.connection y condiciona una precarga secundaria a que la red sea holgada, dejando la crítica siempre activa.
  4. Reduce tu precarga a los dos o tres destinos de mayor valor del recorrido y comprueba que conservas casi toda la velocidad percibida con una fracción del gasto.