Saltar al contenido

Optimizar assets: CSS crítico, preload y caché

Más allá de las imágenes, el resto de la cadena de assets decide si los bytes llegan pronto y se quedan cacheados: alinear e inyectar el CSS crítico con inlineStylesheets, precargar recursos clave con preload y anticipar navegaciones con prefetch, y cachear con Cache-Control e immutable los assets con hash. Cómo las cabeceras dependen del adaptador y el host.

CSS crítico e inlineStylesheets

Una hoja de estilos enlazada con la etiqueta link bloquea la pintura: el navegador no dibuja hasta descargarla y aplicarla. Para hojas pequeñas, ese ida y vuelta cuesta más que el propio CSS, y conviene inyectarlo directamente en el HTML —en línea— para que llegue con el documento y no exija una petición aparte. Astro automatiza esta decisión con build.inlineStylesheets.

TypeScript
// astro.config.mjsimport { defineConfig } from 'astro/config';export default defineConfig({  build: {    // 'auto' inyecta las hojas pequenas y enlaza las grandes    inlineStylesheets: 'auto',  },});

El valor auto —el predeterminado sensato— inyecta las hojas por debajo de un umbral y deja enlazadas las grandes, porque inyectar un CSS voluminoso hincharía el HTML y sabotearía su caché. always fuerza la inyección de todo y never la desactiva. En la mayoría de sitios, auto acierta: los estilos scoped de los componentes, que suelen ser diminutos, viajan con el HTML y pintan sin bloqueo.

Pistas al navegador: preload y prefetch

El navegador descubre los recursos leyendo el HTML de arriba abajo, y a veces eso es tarde. Una pista de recurso le adelanta trabajo. preload le ordena descargar ya un recurso que necesitará pronto pero que descubriría tarde —una fuente, la imagen del LCP—, subiéndolo en la cola de prioridades.

ASTRO
---// En el head del layout---<link  rel="preload"  href="/fuentes/inter.woff2"  as="font"  type="font/woff2"  crossorigin/>

prefetch juega en otro tiempo: anticipa la siguiente navegación descargando en segundo plano, con baja prioridad, una página que el visitante probablemente visitará. Astro trae una integración dedicada que lo hace por ti según una estrategia.

TypeScript
// astro.config.mjsexport default defineConfig({  prefetch: {    prefetchAll: true,    defaultStrategy: 'viewport',  },});

Con eso, los enlaces se precargan según la estrategia elegida —hover, tap, viewport o load— y puedes afinar enlace a enlace con el atributo data-astro-prefetch. Cuando el visitante hace clic, la página siguiente ya está en su caché y la navegación se siente instantánea.

Caché HTTP: hash inmutable y cabeceras

El mayor ahorro no es enviar menos, sino no volver a enviar lo que no cambió. Los assets que Astro emite en _astro/ llevan un hash de contenido en el nombre: si el archivo cambia, cambia su nombre. Esa propiedad permite la caché más agresiva posible —immutable con un año de vida— sin riesgo de servir algo viejo, porque una versión nueva es literalmente otra URL.

Texto
# Assets con hash: cachear para siempre, son inmutablesCache-Control: public, max-age=31536000, immutable# HTML: revalidar, porque su URL no cambia con el contenidoCache-Control: public, max-age=0, must-revalidate

La asimetría es la clave. El HTML conserva su URL aunque su contenido cambie, así que debe revalidarse para no servir una página caduca. Los assets con hash, en cambio, son inmutables por construcción y se cachean sin fecha de vuelta. Dónde se declaran esas cabeceras depende de tu despliegue: en un sitio estático, un archivo de configuración del host; en SSR, el adaptador o el propio middleware.

TypeScript
// En SSR: fijar la cabecera desde un endpoint o middlewarecontext.response.headers.set(  'Cache-Control',  'public, max-age=31536000, immutable',);

Las fuentes web: un caso aparte

Las fuentes merecen atención propia porque combinan dos problemas: bloquean la pintura del texto y pueden provocar CLS al cambiar el alto de las líneas cuando cargan. La primera defensa es font-display, que decide qué hace el navegador mientras la fuente llega: swap muestra ya el texto con una fuente de sistema y lo cambia al cargar la web, evitando el texto invisible.

CSS
@font-face {  font-family: 'Inter';  src: url('/fuentes/inter.woff2') format('woff2');  font-display: swap;}

A eso se suman dos técnicas que ya conoces aplicadas a fuentes: preload para adelantar su descarga y servir solo el subconjunto de caracteres que usas para recortar el peso. Astro 7 incluye además una API de fuentes que automatiza buena parte de esto —descarga, optimización y precarga— para que dejes de orquestarlo a mano. El objetivo es que el titular aparezca pronto, con su tipografía, y sin empujar al resto del contenido cuando llegue.