Optimiza la carga y el procesamiento de WebFont

Una WebFont "completa" que incluya todas las variantes estilísticas, que quizás no necesites, además de todos los glifos, que podrían no usarse, puede generar fácilmente una descarga de varios 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 solucionar el problema de los archivos grandes que contienen todas las variantes, la regla de CSS @font-face está diseñada específicamente para permitirte dividir la familia de fuentes en una colección de recursos. Por ejemplo, subconjuntos Unicode y variantes de diseño distintas.

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

El comportamiento predeterminado

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

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

  1. El navegador solicita el documento HTML.
  2. El navegador comenzará a analizar la respuesta HTML y 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 del CSS, y lo combina con el árbol del DOM para construir el árbol de renderización.
    • Las solicitudes de fuente se envían un vez que el árbol de renderización indica las variantes de fuente necesarias para renderizar 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.
    • Una vez que 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 se puede hacer poco después de que se crea el árbol de renderización, y la solicitud del recurso de fuente es lo que crea el "problema de texto en blanco" en el que el navegador puede renderizar el diseño de la página, pero omite todo 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 alta probabilidad de que tu página necesite una WebFont específica alojada en una URL que conozcas de antemano, puedes aprovechar la priorización de recursos. El uso de <link rel="preload"> activará una solicitud para WebFont al principio de la ruta de acceso de renderización crítica, sin tener que esperar a que se cree el CSSOM.

Cómo personalizar la demora en la renderización de texto

Si bien la precarga aumenta las probabilidades de que una WebFont esté disponible cuando se renderice el contenido de una página, no ofrece garantías. Aún debes considerar cómo se comportan los navegadores cuando renderizas texto que usa font-family, que aún no está disponible.

En la entrada Evita el texto invisible durante la carga de la fuente, puedes ver que el comportamiento predeterminado del navegador no es coherente. Sin embargo, puedes usar font-display para indicarles a los navegadores modernos cómo deseas que se comporten.

Navegadores compatibles

  • 60
  • 79
  • 58
  • 11.1

Origen

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

  1. El primer punto es el período de bloqueo de la fuente. Durante este período, si el tipo de fuente no se carga, cualquier elemento que intente usarla debe renderizarse con un tipo de fuente de resguardo invisible. Si el tipo de fuente se carga correctamente durante el período de bloqueo, se utiliza normalmente.
  2. El período de intercambio de fuentes ocurre inmediatamente después del período de bloqueo de fuentes. Durante este período, si el tipo de fuente no se carga, cualquier elemento que intente usarla debe renderizarse con un tipo de fuente de resguardo. Si el tipo de fuente se carga correctamente durante el período de intercambio, se utiliza con normalidad.
  3. El período de error de la fuente ocurre inmediatamente después del período de intercambio de fuentes. Si el tipo de fuente aún no se cargó cuando comienza este período, se marca como una carga con errores, lo que genera un resguardo de fuente normal. De lo contrario, el tipo de fuente se utiliza normalmente.

Si comprendes estos períodos, puedes usar font-display para decidir cómo se debe renderizar la fuente en función de si se descargó o cuándo se realizó.

Para trabajar con la propiedad font-display, agrégala a tus reglas de @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 font-display de CSS te brindan un gran control sobre la carga y el procesamiento de las fuentes, sin sobrecargar demasiado. Pero si necesitas personalizaciones adicionales y estás dispuesto a incurrir en la sobrecarga que genera la ejecución de JavaScript, hay otra opción.

La API de Font Loading proporciona una interfaz de secuencia de comandos 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 sabes con certeza que se requerirá una variante de fuente específica, puedes definirla e indicar al navegador que inicie una recuperación inmediata del recurso de fuente:

Navegadores compatibles

  • 35
  • 79
  • 41
  • 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, como puedes verificar el estado de la fuente (con el método check()) y hacer un seguimiento del progreso de la descarga, también puedes definir una estrategia personalizada para renderizar texto en tus páginas:

  • Puedes demorar la renderizació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 resguardo para desbloquear la renderización y, luego, inyectar un nuevo estilo que use la fuente deseada cuando esté disponible.

Lo mejor de todo es que también puedes combinar las estrategias anteriores para diferentes contenidos en la página. Por ejemplo, puedes retrasar la representación del texto en algunas secciones hasta que la fuente esté disponible, usar una fuente de resguardo y, luego, volver a renderizarla cuando finalice la descarga de la fuente.

Un correcto almacenamiento en caché es imprescindible

Por lo general, los recursos de fuente son recursos estáticos que no presentan actualizaciones frecuentes. Por lo tanto, son ideales para un vencimiento máximo de duración prolongado. Asegúrate de especificar un encabezado ETag condicional y una óptima política de control de caché para todos los recursos de fuente.

Si tu aplicación web usa un service worker, es apropiado entregar los recursos de fuentes con una estrategia que prioriza la caché en la mayoría de los casos de uso.

No debes almacenar fuentes con localStorage ni IndexedDB, ya que cada una de ellas tiene su propio conjunto de problemas de rendimiento. La caché HTTP del navegador proporciona el mecanismo más adecuado y sólido para entregar recursos de fuente al navegador.

Lista de tareas para cargar WebFont

  • Personaliza la carga y la renderización de fuentes con <link rel="preload">, font-display o la API de Font Loading: El comportamiento de carga diferida predeterminado puede provocar demoras en la renderización del texto. Estas funciones de la plataforma web te permiten anular este comportamiento para determinadas fuentes y especificar estrategias personalizadas de renderización y de tiempo de espera 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 de larga duración y un token de revalidación para permitir la reutilización eficiente de la fuente entre diferentes páginas. Si usas un service worker, la estrategia que priorice la caché es adecuada.

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 cumpliendo las prácticas recomendadas de optimización de fuentes web a lo largo del tiempo: