Estrategia de fuentes web:
los cuatro pasos que siempre aplico
Autoalojamiento, WOFF2, subconjunto y preload, medidos en esta web.
Todo el texto de esta web utiliza la fuente tipográfica JetBrains Mono. Así que, si la fuente va lenta, va lenta la página entera. Los tres font-weight que uso suman 825 KB en los TTF tal y como los publica JetBrains. Lo que se carga de verdad son 65 KB, desde mi propio servidor y pedidos antes de que el navegador sepa siquiera que los va a necesitar. Así es cómo logro hacerlo consistentemente:
Autoaloja la fuente
Lo primero que hago siempre es quitar la importación de fuente de un servicio de terceros y servirla desde mi propio dominio. Un enlace a Google Fonts obliga al navegador a hablar con dos servidores nuevos: uno para la hoja de estilos, que bloquea el renderizado, y otro para el archivo de fuente al que apunta esa hoja. Cada servidor nuevo cuesta una consulta DNS y un handshake TLS antes de que se mueva un solo byte. Al autoalojarla, todo eso se queda en una única petición por una conexión que la página ya tenía abierta.
Un preconnect puede adelantar esos handshakes, pero no se salta la hoja de estilos
de en medio. Y el viejo argumento de que el visitante ya tiene la copia de Google en caché dejó
de valer hacia 2020, cuando los navegadores empezaron a guardar una caché aparte para cada web.
Además, si el archivo es tuyo, las cabeceras de caché también. Un archivo de fuente nunca cambia sin cambiar también de nombre, así que el navegador puede guardarlo un año entero sin volver a preguntar:
/assets/fonts/*
Cache-Control: public, max-age=31536000, immutable
Lo hago por la velocidad, pero no es el único beneficio: una dependencia externa menos y ningún servidor ajeno enterándose de quién entra. Y eso último no es teórico: en 2022, un tribunal alemán condenó al dueño de una web a indemnizar a un visitante por usar Google Fonts, porque enviaba su IP a Google sin su consentimiento.
Google Fonts
- HTML
- DNS
- TLS
- CSS
- DNS
- TLS
- WOFF2
fonts.googleapis.com -> fonts.gstatic.com
Autoalojada
- HTML
- WOFF2
miguelpv.dev — conexión ya abierta
Sírvela en woff2
La elección del formato es más simple de lo que parece: woff2 es el formato de
fuente web más comprimido que hay, y todos los navegadores para los que desarrollo lo entienden
desde hace años. Los mismos glifos con un tercio de los bytes: JetBrains Mono Regular pesa
274 KB en TTF y 92 KB en WOFF2.
Así que sirvo WOFF2 y nada más: un @font-face por font-weight, cada uno apuntando a un
único archivo. Sin formatos de reserva ni una lista de src que el navegador tenga
que ir probando.
@font-face {
font-family: 'JetBrains Mono';
font-style: normal;
font-weight: 400;
src: url('/assets/fonts/jetbrains-mono-v24-latin-regular.woff2')
format('woff2');
}
Haz un subconjunto y quita los font-weight que no uses
En proporción, aquí está el mayor recorte: el WOFF2 ya dejaba los archivos en un tercio, y el
subconjunto vuelve a dividirlos entre más de cuatro. Un archivo de fuente completo trae cirílico,
griego, vietnamita y cientos de símbolos que esta web no usa nunca, así que sólo sirvo el
subconjunto latin. Cubre también la versión en español, porque la á, la é, la ñ, el ¿ y el ¡
están todos en él, así que un mismo archivo sirve para los dos idiomas. El WOFF2 completo pesa
92 KB; el latin, 21 KB.
Después recorto los font-weight a los que el diseño usa de verdad. Aquí son tres (regular, medium y semibold) y ninguna cursiva: cada peso o estilo de más es otro archivo que descargar.
- TTF, completa 825 KB
- WOFF2, completa 280 KB
- WOFF2, latino 65 KB
Precarga las que importan
El navegador no pide una fuente cuando lee el @font-face. Espera a haber analizado
la página, aplicado los estilos y encontrado algún texto que use esa fuente. Eso es tarde,
incluso con el CSS en línea, como aquí. Un preload en el <head> lanza la
descarga en el acto, en paralelo con todo lo demás:
<link rel="preload" href="/assets/fonts/jetbrains-mono-v24-latin-regular.woff2"
as="font" type="font/woff2" crossorigin />
Aquí hay dos detalles importantes. crossorigin no es opcional, ni siquiera en tu
propio dominio: los navegadores siempre piden las fuentes en modo CORS, así que un preload sin ese
atributo no coincide con la petición real y la fuente se descarga dos veces. Y precargo justo las
fuentes que usa la primera pantalla (aquí, las tres), ni una más. Si lo precargas todo, tus
fuentes acaban peleándose con tus propios recursos críticos por el ancho de banda.
Sin preload
- HTML
- parseo
- WOFF2
- texto
Con preload
- HTML
- parseo
- texto
- WOFF2
<head> todavía se está leyendo, así que la fuente ya está ahí
cuando el texto la necesita. Ilustrativo, no a escala.
Cuándo lo haría de otra forma
Estos cuatro pasos son mi punto de partida, no una ley: son lo que necesitaba esta web. Hay cosas que me harían cambiar de idea:
- Más fuentes: cuantas más familias y pesos necesite un diseño, más importa recortar caracteres y pesos, y más difícil es precargarlo todo sin atascar la ruta crítica. A partir de cierto punto, la solución de verdad es usar menos fuentes, no cargarlas con más maña.
-
Un idioma fuera del alfabeto latino: si algún día añado uno, serviría sus glifos como un
subconjunto aparte con
unicode-range, para que quien lee en inglés o en español no tenga que descargarlos nunca. -
Navegadores antiguos de verdad: sólo sirvo WOFF2 porque todos los navegadores para los que
desarrollo lo entienden. Si tuviera que llegar a navegadores mucho más viejos, añadiría un
woffde reserva a la listasrc, y esos bytes de más sólo se los descargarían ellos. - Una fuente que no consigo hacer rápida: si una tipografía corporativa tuviera que aparecer sí o sí y no lograra hacerla pequeña, recortarla ni precargarla, lo honesto sería cambiar de fuente, no servir una lenta.
Y la mejora no es exclusiva de mi web. En una web que revisé hace poco con un amigo, arreglar sólo las fuentes (autoalojarlas, WOFF2, subconjuntos, menos familias y precargar las adecuadas) redujo su peso unas 10 veces. La página pasó de un 47 en PageSpeed, con el FCP y el LCP en torno a los 10 segundos, a un 92–96, con ambas métricas entre 2,0 y 2,7 s. Mismo contenido, mismo diseño. Las fuentes simplemente dejaron de ser el cuello de botella.
Esa es toda la estrategia: haz que la fuente pese poco y sírvela pronto. Abre la pestaña Red de las DevTools, busca tus archivos de fuente y mira cuánto pesan y cuándo empiezan a descargarse. Esas dos cifras te dicen por qué paso empezar.