Optimiza la carga y el procesamiento de WebFont

Una fuente web "completa" que incluya todas las variantes estilísticas, que quizá no necesites, y todos los glifos, que quizá no se usen, fácilmente puede implicar una descarga de muchos megabytes. En esta publicación, descubrirás cómo optimizar la carga de WebFonts para que los visitantes solo descarguen lo que usarán.

Para abordar el problema de los archivos grandes que contienen todas las variantes, la regla CSS @font-face está diseñada específicamente para permitirte dividir la familia de fuentes en una colección de recursos. Por ejemplo, subconjuntos de Unicode y variantes de estilo distintas.

Dadas estas declaraciones, el navegador descifrará las variantes y los subconjuntos necesarios, y descargará el conjunto mínimo requerido para representar el texto, lo cual es muy conveniente. Sin embargo, si no eres cuidadoso, también puede crear un cuello de botella de rendimiento en la ruta de acceso de representación crítica y retardar la representación del texto.

El comportamiento predeterminado

La carga diferida de fuentes conlleva una consecuencia oculta importante que puede retrasar la renderización del texto. El navegador debe construir el árbol de renderización, que depende de los árboles del DOM y el CSSOM, antes de saber qué recursos de fuente necesita para renderizar el texto. Como resultado, las solicitudes de fuentes se demoran hasta mucho después de otros recursos críticos y la representación del texto en el navegador puede quedar bloqueada hasta que se obtenga el recurso.

Ruta de acceso de representación crítica de fuentes

  1. El navegador solicita el documento HTML.
  2. El navegador comienza a analizar la respuesta HTML y a construir el DOM.
  3. El navegador detecta CSS, JS y otros recursos, y envía solicitudes.
  4. El navegador construye el CSSOM una vez que recibe todo el contenido CSS, y lo combina con el árbol del DOM para construir el árbol de representación.
    • Las solicitudes de fuentes se envían un vez que el árbol de representación indica las variantes de fuente que se necesitan para representar el texto especificado en la página.
  5. El navegador realiza un diseño y pinta contenido en la pantalla.
    • Si la fuente aún no está disponible, es posible que en el navegador no se representen los píxeles de texto.
    • Cuando la fuente está disponible, el navegador pinta los píxeles de texto.

La “carrera” entre la primera pintura del contenido de la página, que puede ocurrir poco después de la construcción del árbol de representación, y la solicitud del recurso de fuente son los elementos que generan el “problema de texto en blanco”, en el que el navegador puede representar el diseño de la página, pero omite el texto.

Si precargas WebFonts y usas font-display para controlar el comportamiento de los navegadores con fuentes no disponibles, puedes evitar páginas en blanco y cambios de diseño debido a la carga de fuentes.

Precarga tus recursos de WebFont

Si existe una probabilidad alta de que la página necesite una fuente para sitios web específica alojada en una URL conocida de antemano, puedes aprovechar la priorización de recursos. El uso de <link rel="preload"> activará una solicitud de la fuente para sitios web al comienzo de la ruta de acceso de renderización crítica, sin tener que esperar a que se cree el CSSOM.

Personaliza la demora de renderización de texto

Si bien a partir de la precarga es más probable que una fuente para sitios web esté disponible al representar el contenido de una página, no hay ninguna garantía de que esto ocurra. Deberás tener en cuenta cómo se comportan los navegadores cuando renderizan texto que usa un font-family que aún no está disponible.

En la publicación Evita el texto invisible durante la carga de fuentes, puedes ver que el comportamiento predeterminado del navegador no es coherente. Sin embargo, puedes indicarles a los navegadores modernos cómo quieres que se comporten con font-display.

Navegadores compatibles

  • Chrome: 60.
  • Edge: 79.
  • Firefox: 58.
  • Safari: 11.1.

Origen

De manera similar al comportamiento de tiempo de espera de las fuentes existentes que implementan algunos navegadores, font-display segmenta la vida útil de una descarga de fuente en tres períodos principales:

  1. El primer período es el período de bloqueo de fuente. En él, si el tipo de fuente no se carga, cualquier elemento que intente usarla debe representarse con un tipo de fuente de reserva invisible. Si el tipo de fuente se carga correctamente durante el período de bloqueo, entonces se utiliza de manera normal.
  2. El período de intercambio de fuente ocurre inmediatamente después del período de bloqueo. En él, si el tipo de fuente no se carga, cualquier elemento que intente usarla debe representarse con un tipo de fuente de reserva. Si el tipo de fuente se carga correctamente durante el período de intercambio, entonces se utiliza de manera normal.
  3. El período de error de fuente ocurre inmediatamente después del período de intercambio de fuente. Si el tipo de fuente aún no se cargó cuando comienza este período, se lo marca como una carga fallida y se utiliza la fuente de reserva. De lo contrario, el tipo de fuente se utiliza de manera normal.

Comprender estos períodos significa que puedes usar font-display para decidir de qué modo debe renderizarse la fuente según si se descargó o cuándo se descargó.

Para trabajar con la propiedad font-display, agrégala a tus reglas @font-face:

@font-face {
  font-family: 'Awesome Font';
  font-style: normal;
  font-weight: 400;
  font-display: auto; /* or block, swap, fallback, optional */
  src: local('Awesome Font'),
       url('/fonts/awesome-l.woff2') format('woff2'), /* will be preloaded */
       url('/fonts/awesome-l.woff') format('woff'),
       url('/fonts/awesome-l.ttf') format('truetype'),
       url('/fonts/awesome-l.eot') format('embedded-opentype');
  unicode-range: U+000-5FF; /* Latin glyphs */
}

Actualmente, font-display admite el siguiente rango de valores:

  • auto
  • block
  • swap
  • fallback
  • optional

Para obtener más información sobre la precarga de fuentes y la propiedad font-display, consulta las siguientes publicaciones:

La API de Font Loading

Si se usan en conjunto, <link rel="preload"> y el CSS font-display te brindan un gran control sobre la carga y la renderización de fuentes, sin agregar mucha sobrecarga. Ahora bien, si necesitas un nivel mayor de personalización y estás dispuesto a soportar la sobrecarga que presenta la ejecución de JavaScript, hay otra opción.

La Font Loading API proporciona una interfaz de escritura para definir y manipular los tipos de fuente CSS, realizar un seguimiento del progreso de la descarga y anular su comportamiento predeterminado de carga diferida. Por ejemplo, si estás seguro de que se requerirá una variante de fuente determinada, puedes definirla e indicar al navegador que inicie una obtención inmediata del recurso de fuente:

Navegadores compatibles

  • Chrome: 35.
  • Edge: 79.
  • Firefox: 41.
  • Safari: 10.

Origen

var font = new FontFace("Awesome Font", "url(/fonts/awesome.woff2)", {
  style: 'normal', unicodeRange: 'U+000-5FF', weight: '400'
});

// don't wait for the render tree, initiate an immediate fetch!
font.load().then(function() {
  // apply the font (which may re-render text and cause a page reflow)
  // after the font has finished downloading
  document.fonts.add(font);
  document.body.style.fontFamily = "Awesome Font, serif";

  // OR... by default the content is hidden,
  // and it's rendered after the font is available
  var content = document.getElementById("content");
  content.style.visibility = "visible";

  // OR... apply your own render strategy here...
});

Además, debido a que puedes comprobar el estado de la fuente (a través del método check()) y realizar un seguimiento del progreso de la descarga, también puedes definir una estrategia personalizada para renderizar texto en tus páginas:

  • Puedes demorar la representación de todo el texto hasta que la fuente esté disponible.
  • Puedes implementar un tiempo de espera personalizado para cada fuente.
  • Puedes usar la fuente de reserva para desbloquear la representación e inyectar un nuevo estilo que use la fuente deseada cuando esté disponible.

Lo mejor de todo es que también puedes combinar estas estrategias para contenido diferente en la página. Por ejemplo, puedes demorar la representación de texto en algunas secciones hasta que la fuente esté disponible, usar una fuente de reserva y, luego, volver a realizar la representación cuando la descarga de la fuente haya finalizado.

Un correcto almacenamiento en caché es obligatorio

Por lo general, los recursos de fuentes son recursos estáticos que no presentan actualizaciones frecuentes. En consecuencia, son ideales para una vida útil prolongada. Asegúrate de especificar un encabezado ETag condicional y una política óptima de Cache-Control para todos los recursos de fuente.

Si la aplicación web usa un service worker, proporcionar recursos de fuente con una estrategia en la que se prioriza la caché es adecuado en la mayoría de los casos de uso.

No debes almacenar las fuentes con localStorage ni IndexedDB, ya que cada una tiene sus propios problemas de rendimiento. La caché HTTP del navegador ofrece el mecanismo más adecuado y sólido para proporcionar recursos de fuente al navegador.

Lista de tareas para cargar WebFont

  • Personaliza la carga y la representación de fuentes con <link rel="preload">, font-display o la API de Font Loading: El comportamiento de carga diferida predeterminado puede demorar la representación de texto. Estas funciones de la plataforma web te permiten anular este comportamiento para fuentes particulares y especificar estrategias de renderización y tiempo de espera personalizadas para diferentes contenidos de la página.
  • Especifica políticas de revalidación y almacenamiento en caché óptimo: Las fuentes son recursos estáticos que se actualizan con poca frecuencia. Asegúrate de que tus servidores proporcionen una marca de tiempo de max-age prolongada y un token de revalidación para permitir la reutilización eficaz de fuentes en diferentes páginas. Si se utiliza un trabajador de servicio, corresponde emplear una estrategia en la que se priorice la caché.

Pruebas automatizadas del comportamiento de carga de WebFont con Lighthouse

Lighthouse puede ayudarte a automatizar el proceso de asegurarte de seguir las prácticas recomendadas de optimización de fuentes web.

Las siguientes auditorías pueden ayudarte a asegurarte de que tus páginas sigan las prácticas recomendadas de optimización de fuentes web a lo largo del tiempo: