Rendimiento tipográfico y CLS
El estado intermedio entre el primer pintado y la fuente lista: gobernar el intercambio con font-display, entender el desplazamiento de maquetación que provoca el cambio de fuente y anularlo con fallbacks métricos optimizados basados en size-adjust, y reservar el preload para la fuente crítica del primer viewport.
font-display: gobernar el intercambio
La propiedad font-display le dice al navegador cómo comportarse mientras la fuente carga, repartiendo dos periodos: uno de bloqueo, en el que el texto puede quedar invisible esperando la fuente, y uno de intercambio, en el que se muestra un respaldo hasta que la real llega. Sus valores gradúan esa negociación: swap muestra el respaldo de inmediato y cambia al llegar la fuente; block oculta el texto un instante antes de rendirse al respaldo; fallback es un término medio; y optional da un margen mínimo y, si la fuente no llega a tiempo, se queda con el respaldo sin cambiar en esa carga.
---// astro.config.mjsexport default defineConfig({ fonts: [ { provider: fontProviders.google(), name: 'Inter', cssVariable: '--font-inter', display: 'swap', }, ],});La elección tiene consecuencias opuestas. swap garantiza que el texto siempre se vea, pero a costa de un cambio visible que puede desplazar la maquetación. optional es la mejor para las métricas de rendimiento, porque evita el salto por completo, pero acepta que en una red lenta el visitante quizá no llegue a ver tu fuente en esa visita. No hay un valor correcto universal; hay un valor correcto para cada compromiso entre certeza de mostrar la fuente y estabilidad visual.
Fallbacks métricos: el truco contra el CLS
El salto no lo causa el cambio de fuente en sí, sino que la fuente de respaldo y la real tengan métricas distintas: distinta altura de las minúsculas, distinta anchura de avance. Cuando el respaldo ocupa más o menos espacio que la fuente definitiva, el texto se recompone al intercambiar y todo lo que hay debajo salta. La cura no es evitar el respaldo, sino hacer que ocupe exactamente el mismo espacio que la fuente real.
Eso es lo que hace Astro por defecto. A partir de la última familia genérica de tu pila de fallbacks, genera un @font-face de respaldo optimizado que ajusta sus métricas, con size-adjust y los descriptores de ascenso y descenso, para calcar la caja de la fuente real. Mientras la fuente carga, el respaldo ya ocupa su sitio definitivo, así que cuando llega el intercambio no se mueve nada.
---// astro.config.mjsexport default defineConfig({ fonts: [ { provider: fontProviders.google(), name: 'Inter', cssVariable: '--font-inter', fallbacks: ['sans-serif'], optimizedFallbacks: true, }, ],});El respaldo optimizado que Astro inyecta se parece conceptualmente a esto: una familia de respaldo local que hereda las métricas de la fuente real mediante size-adjust, de modo que un carácter ocupe lo mismo en ambas.
@font-face { font-family: 'Inter fallback'; src: local('Arial'); size-adjust: 107%; ascent-override: 90%; descent-override: 22%;}Cada descriptor cumple un papel: size-adjust escala el glifo para igualar la anchura de avance, y los ascent-override y descent-override fijan la altura de la caja de línea para que el interlineado coincida. Juntos consiguen que una línea de respaldo y una línea de la fuente real ocupen el mismo rectángulo, condición necesaria para que el intercambio no empuje nada.
optimizedFallbacks está activo por defecto y es lo que quieres en casi todos los casos. Solo lo desactivas, poniéndolo en false, si necesitas control manual absoluto sobre la pila de respaldo y prefieres definir tú los descriptores. La última entrada de fallbacks debe ser una familia genérica, como sans-serif o monospace, porque es de ella de donde Astro deriva el respaldo métrico.
preload selectivo
La tercera palanca, ya presentada con el componente <Font />, es la precarga. Aquí su papel es de rendimiento puro: adelantar la fuente crítica del primer viewport acorta el tiempo en que se muestra el respaldo, pero precargar de más retrasa el contenido importante.
---import { Font } from 'astro:assets';---<head> <!-- solo la fuente del cuerpo, que domina el primer viewport --> <Font cssVariable="--font-inter" preload /> <!-- la de titulares decorativos, a demanda --> <Font cssVariable="--font-display" /></head>La regla se mantiene: precarga solo la fuente que domina lo visible al abrir la página, y deja las demás a demanda. Una precarga quirúrgica reduce el tiempo con respaldo justo donde el ojo mira primero, sin robar prioridad al resto de la carga.