Una de las partes mas relevantes del diseño web es la selección de las fuentes que se utilizarán. Estas tienen efecto directo en la legibilidad de nuestros contenidos, el branding y la velocidad de carga de nuestro sitio. Esto a día de hoy puede parecer algo trivial, pero hacer un uso optimizado de las fuentes en nuestra página marca la diferencia a nivel de experiencia de usuario.

En este artículo vamos a ver cuáles son los problemas típicos generados por una carga de fuentes mal optimizada y las mejores prácticas para evitarlos.

Principales problemas que encontramos al añadir fuentes en nuestra página web

A nivel de experiencia de usuario hay dos interacciones que encontramos cuando la carga de las fuentes no se está realizando de forma eficiente. Estas son las llamadas Flash of Unstyled Tex (FOUT) y Flash of Invisible Text (FOIT), por el nombre quizás no te suenan pero con este gif estoy seguro que eres capaz de identificarlas en algún sitio web.

FOIT and FOUT effect

Estos dos efectos ocurren porque en el momento de renderizado de la página la fuente personalizada que queremos utilizar aún no se ha cargado. En función de la propiedad de css font-display que utilicemos se dará el efecto FOIT o el FOUT.

Por ejemplo, si utilizamos la propiedad "block" estaremos priorizando el "bloqueo" hasta que cargue nuestra fuente, por lo tanto tendremos el efecto de ver en blanco los textos de la página. Por otro lado, si utilizamos la propiedad "swap" el tiempo de bloqueo que establecemos es mucho menor al mostrar la fuente predeterminada del sistema o navegador antes de cargar nuestra fuente personalizada y es cuando vemos el efecto FOUT.

Estas interacciones en redes lentas son habituales, pero cuando empiezan a suceder en redes de velocidad estándar son un indicio claro de que la carga de las fuentes en nuestro sitio puede ser optimizada.

A parte de penalizar la experiencia de usuario, los efectos de FOIT y FOUT también afectan directamente en métricas como el comulative layout shift y el largest contentful paint de nuestra página, estos son indicadores utilizados por Google en la iniciativa Web Vitals con el objetivo de promover un conjunto de buenas prácticas para que todas las páginas web proporcionen una buena experiencia de usuario.

Ahora que ya hemos visto los problemas que pueden suceder cuando añadimos fuentes personalizadas a nuestro sitio web, veamos cómo resolverlos.

Como cargar fuentes personalizadas en nuestra página web

La mejor opción sí queremos priorizar la velocidad por delante de todo es utilizar directamente fuentes que sean Web safe fonts. Estas fuentes están incluidas en la mayoría de sistemas operativos y por lo tanto el navegador debería ser capaz de renderizarlas. A parte de las Web Safe Fonts tenemos las fuentes que utiliza cada sistema operativo por ejemplo en Mac la San Francisco o en Android la Roboto. Estas se conocen como System Fonts Stack  y también nos dan la ventaja de poder ser renderizadas sin tener que hacer ninguna petición externa para descargar la fuente.

Pese a tener esta variedad de opciones, muchas veces este abanico de fuentes no es suficiente ya sea por imagen de marca o por obtener una mayor consistencia entre dispositivos y navegadores, aquí es cuando entra el uso de fuentes personalizadas.

Hay muchas formas para cargar fuentes personalizadas en nuestra web pero estas son nuestras 4recomendaciones clave para que obtengas el mejor rendimiento.

1. Alojar la fuente

Una de las primeras acciones que podemos realizar es alojar en nuestro propio servidor la fuente que se quiere utilizar, en muchos casos se utiliza directamente la CDN de Google Fonts para cargar las páginas ya que es una forma muy cómoda y sencilla de cargar fuentes. Pero si queremos mejorar la carga de las fuentes podemos servirlas desde nuestro servidor con ficheros optimizados para nuestro sitio. Este es el primer paso para que la carga sea rápida y consistente.

Además una de las principales ventajas de usar Google Fonts era la posibilidad de cachear las fuentes entre diferentes sitios web, pero las nuevas versiones de Chrome y Safari han implementado lo que se conoce como "Cache partitiong", que en simples palabras quiere decir que los ficheros cacheados por un sitio A no están disponibles por un sitio B.

2.  Utilizar el atributo preload

Una vez ya tenemos alojada nuestra fuente, el siguiente paso es cargarla en nuestra página. Para ello es muy interesante utilizar el atributo rel="preload", esto lo que hará será priorizar la descarga de la fuente en el ciclo de carga de nuestra web. Si además lo acompañamos con los atributos as="font" y type="font/woff2" le estaremos diciendo al navegador que este recurso es una fuente y podrá priorizarlo mejor dentro de la cola de recursos.

<head>
	<link
	 rel="preload"
	 href="/fonts/WorkSans-VariableFont.woff2"
	 as="font"
	 type="font/woff2"
	 crossOrigin="anonymous"
	></link>
</head>

Cabe remarcar que en el type tenemos que utilizar el formato de fuente que estemos utilizando, en este caso es woff2 pero podría ser ttf, woff o otro formato existente.

3. Utilizar la propiedad font-display adecuada

Una vez añadida la fuente a nuestra página tenemos que añadirla a nuestros estilos para poder utilizarla. Para ello podemos utilizar las reglas @font-face donde indicaremos la ruta del fichero (src), el nombre que queremos utilizar para hacer uso de la fuente (font-family) y la forma en la que queremos que se visualice la fuente en función de si está cargada o no (font-display).

@font-face {
  font-family: 'WorkSans';
  font-display: swap;
  src: url('/fonts/WorkSans-VariableFont_wght.woff2') format('woff2');
}

body {
  font-family: 'WorkSans', -apple-system, BlinkMacSystemFont, avenir next,
    avenir, helvetica neue, helvetica, Ubuntu, roboto, noto, segoe ui, arial,
    sans-serif;
}

Dentro de las formas de carga de la fuente tenemos las siguientes opciones:

  • auto: La estrategia de visualización de fuentes es definida por el agente.
  • block: Da a la fuente un período de block corto y un período de swap infinito.
  • swap: Da a la fuente un período de block extremadamente pequeño y un período de swap infinito.
  • fallback: Da a la fuente un período de block extremadamente pequeño y un período de swap corto.
  • optional: Le da a la fuente un período de block extremadamente pequeño y no tiene período de swap.

Nuestra recomendación es utilizar la opción de swap con una fuente de fallback lo más parecida posible a la personalizada para minimizar el efecto de FOUT o la optional si no nos importa que en algunos casos pueda no llegar a cargarse la fuente.

4. Optimizar los ficheros de las fuentes que vamos a utilizar

Llegados a este punto ya disponemos de la fuente que queremos en nuestra página pero aún podemos optimizar un poco más la carga de nuestras fuentes si optimizamos los ficheros que utilizamos para nuestra página.

La primera recomendación es utilizar lo que se conoce como una fuente variable, esto simplemente es un fichero que contiene las distintas variaciones de una fuente. De esta manera no tenemos que hacer múltiples peticiones para descargar la fuente, sino que haciendo una sola petición ya tendremos las distintas variantes disponibles. Para obtener una fuente variable podemos descargar una fuente de Google Fonts y dentro de la carpeta comprimida veremos que hay un fichero donde incluye "variable". Esta es nuestra fuente variable.

Font files

Con esto ya habremos mejorado una parte pero aun así seguimos teniendo un inconveniente, el fichero que cargamos es de 397KB y esto en redes lentas puede significar un tiempo de carga bastante elevado. Optimizar este fichero es posible gracias al uso de formatos con una mayor compresión que el ttf como son el formato woff2 o woff y de la propiedad de font subseting que nos permitirá utilizar solo los caracteres que necesitemos de nuestra fuente.

Para poder realizar la compresión haremos uso de la herramienta Fontools. Para instalarla y poder usar los formatos wooff2 y woff tendremos que tener python instalado en nuestro ordenador y ejecutar el siguiente comando en la terminal.

pip install fonttools zopfli brotli

Una vez tenemos la herramienta instalada para comprimir nuestra fuente tenemos que definir los unicodes que queremos utilizar, un conjunto interesante para empezar es el Latin Subset, este cubre textos en Ingles, Frances, Español o Alemán.

U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20ACU+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFF

Una vez decididos los unicodes podemos almacenarlos en un fichero que llamaremos unicodes.txt y utilizar el siguiente comando para crear el fichero optimizado.

//Para crear el fichero en woff
pyftsubset WorkSans-VariableFont_wght.ttf --unicodes-file=unicodes.txt --flavor=woff --with-zopfli

//Para crear el fichero en woff2
pyftsubset WorkSans-VariableFont_wght.ttf --unicodes-file=unicodes.txt --flavor=woff2

Con esto ya tendríamos nuestra fuente optimizada lista para añadir a nuestra página web, si tienes curiosidad por analizar la fuente puedes hacer uso de la herramienta web wakamaifondue que permite analizar este tipo de ficheros.

Wakamaifondue site

Pero si esta compresión aún no ha sido suficiente podemos llevarlo un paso más allá, escaneando nuestra página web para ver que unicodes se utilizan y crear así nuestro fichero en base a estos.

Para ello podemos hacer uso de la herramienta Glyphanger que podemos instalar con el comando.

npm install -g glyphhanger

Una vez instalada podemos escanear las diferentes páginas de nuestro sitio web usando el siguiente comando.

glyphhanger <https://tonimas.dev/>
U+20,U+2C-2E,U+30-32,U+35,U+41-43,U+46-49,U+4C,U+4D,U+4F,U+50,U+52-54,U+56,U+57,U+5F,U+61-70,U+72-79,U+A9,U+2019

Como vemos este nos devolverá el rango de unicodes necesarios con el que podremos crear el fichero usando el comando pyftsubset. La compresión final que obtenemos es muy significativa ya que pasamos de un fichero que inicialmente era de 397KB a uno de 20KB.

Fonts compressed

Finalmente para cargar nuestra fuente usando subseting con la regla @font-face lo haremos de la forma siguiente.

@font-face {
  font-family: 'WorkSans';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/fonts/WorkSans-VariableFont_wght.woff2') format('woff2');
  unicode-range: U+20, U+2C-2E, U+30-32, U+35, U+41-43, U+46-49, U+4C, U+4D,
    U+4F, U+50, U+52-54, U+56, U+57, U+5F, U+61-70, U+72-79, U+A9, U+2019;
}

body {
  font-family: 'WorkSans', -apple-system, BlinkMacSystemFont, avenir next,
    avenir, helvetica neue, helvetica, Ubuntu, roboto, noto, segoe ui, arial,
    sans-serif;
}

Conclusiones

Como hemos podido comprobar en este artículo la carga de las fuentes en una web es un aspecto mucho menos trivial de lo que pueda parecer en un principio pero a la vez es una de las mejoras más sencillas de hacer para mejorar la experiencia de usuario, así que esperamos que a partir de ahora podáis aplicar algunos de estos consejos en vuestras páginas.