Una WebFont "completa" que incluye todas las variantes de estilo, que es posible que no necesites, además de todos los glifos, que es posible que no se usen, 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 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.
Con estas declaraciones, el navegador determina los subconjuntos y las variantes necesarios, y descarga el conjunto mínimo necesario para renderizar el texto, lo que es muy conveniente. Sin embargo, si no tienes cuidado, también puede crear un cuello de botella de rendimiento en la ruta de renderización crítica y retrasar la renderización de texto.
El comportamiento predeterminado
La carga diferida de fuentes tiene una implicación oculta importante que puede retrasar la renderización de texto. El navegador debe construir el árbol de renderización, que depende de los árboles DOM y CSSOM, antes 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 es posible que se bloquee el navegador para que no renderice texto hasta que se recupere el recurso.
- El navegador solicita el documento HTML.
- El navegador comienza a analizar la respuesta HTML y a construir el DOM.
- El navegador descubre CSS, JS y otros recursos, y envía solicitudes.
- El navegador construye el CSSOM después de recibir todo el contenido de CSS y lo combina con el árbol DOM para construir el árbol de renderización.
- Las solicitudes de fuentes se envían después de que el árbol de renderización indica qué variantes de fuente se necesitan para renderizar el texto especificado en la página.
- El navegador realiza el diseño y pinta el contenido en la pantalla.
- Si la fuente aún no está disponible, es posible que el navegador no renderice ningún píxel 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 compila 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 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 es muy probable 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 la WebFont al principio de la ruta de renderización crítica, sin tener que esperar a que se cree el CSSOM.
Personaliza el retraso de renderización de texto
Si bien la carga previa aumenta las probabilidades de que una WebFont esté disponible cuando se renderiza el contenido de una página, no ofrece garantías.
Aún debes considerar 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
.
Al igual que los comportamientos de tiempo de espera de fuentes existentes que implementan algunos navegadores, font-display
segmenta la vida útil de una descarga de fuente en tres períodos principales:
- El primer período es el período del bloque de fuente. Durante este período, si no se carga la fuente, cualquier elemento que intente usarla debe renderizarse con una fuente de resguardo invisible. Si la fuente se carga correctamente durante el período de bloqueo, se usará de forma normal.
- El período de intercambio de fuentes ocurre inmediatamente después del período de bloqueo de fuentes. Durante este período, si no se carga la fuente, cualquier elemento que intente usarla debe renderizarse con una fuente de resguardo. Si la fuente se carga correctamente durante el período de intercambio, se usa de forma normal.
- El período de falla de la fuente ocurre inmediatamente después del período de intercambio de fuentes. Si el tipo de letra aún no se cargó cuando comienza este período, se marca como una carga fallida, lo que provoca el resguardo de fuente normal. De lo contrario, el tipo de letra se usa de forma normal.
Comprender estos períodos significa que puedes usar font-display
para decidir cómo se debe renderizar tu fuente según si se descargó o no, y cuándo.
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:
- Evita el texto invisible durante la carga de la fuente
- Cómo controlar el rendimiento de la fuente con font-display
- Precarga fuentes opcionales para evitar el cambio de diseño y los destellos de texto invisible (FOIT)
La API de Font Loading
Si se usan juntos, <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.
Sin embargo, 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 secuencias de comandos para definir y manipular los tipos de letra de CSS, hacer un seguimiento del progreso de la descarga y anular su comportamiento de carga diferida predeterminado. Por ejemplo, si estás seguro de que se requiere una variante de fuente en particular, puedes definirla y decirle al navegador que inicie una recuperación inmediata del recurso de fuente:
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 (a través del 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 detener toda la renderización de 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, insertar un estilo nuevo que use la fuente deseada cuando esté disponible.
Lo mejor de todo es que también puedes combinar las estrategias anteriores para diferentes tipos de contenido en la página. Por ejemplo, puedes retrasar la renderización de texto en algunas secciones hasta que la fuente esté disponible, usar una fuente de resguardo y, luego, volver a renderizar después de que finalice la descarga de la fuente.
El almacenamiento en caché adecuado es fundamental
Por lo general, los recursos de fuente son recursos estáticos que no reciben actualizaciones frecuentes. Como resultado, son ideales para un vencimiento de max-age largo. Asegúrate de especificar un encabezado de ETag condicional y una política de Cache-Control óptima para todos los recursos de fuente.
Si tu aplicación web usa un trabajador de servicio, la entrega de recursos de fuente con una estrategia de caché en primer lugar es adecuada para la mayoría de los casos de uso.
No debes almacenar fuentes con localStorage
ni IndexedDB, ya que cada una tiene su propio conjunto de problemas de rendimiento.
La caché HTTP del navegador proporciona el mecanismo más eficaz y sólido para entregar recursos de fuentes al navegador.
Lista de tareas para cargar WebFont
- Personaliza la carga y renderización de fuentes con
<link rel="preload">
,font-display
o la API de Font Loading: El comportamiento predeterminado de carga diferida puede retrasar la renderización de texto. Estas funciones de la plataforma web te permiten anular este comportamiento para fuentes en particular y especificar estrategias de renderización y tiempo de espera personalizadas para el contenido diferente de la página. - Especifica políticas de revalidación y almacenamiento en caché óptimas: Las fuentes son recursos estáticos que se actualizan con poca frecuencia. Asegúrate de que tus servidores proporcionen una marca de tiempo de tiempo de vida máximo de larga duración y un token de validación para permitir la reutilización eficiente de fuentes entre diferentes páginas. Si usas un trabajador de servicio, es adecuada una estrategia de almacenamiento en caché en primer lugar.
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: