Una nueva forma de reducir el impacto de la carga de fuentes: descriptores de fuentes CSS

Publicado: 2022-03-10
Resumen rápido ↬ Las fuentes web a menudo son terribles para el rendimiento web y ninguna de las estrategias de carga de fuentes es particularmente efectiva para solucionarlo. Las próximas opciones de fuentes pueden finalmente cumplir la promesa de facilitar la alineación de las fuentes alternativas con las fuentes finales.

La carga de fuentes ha sido durante mucho tiempo un problema del rendimiento web, y realmente no hay buenas opciones aquí. Si desea usar fuentes web, sus opciones son básicamente Flash de texto invisible (también conocido como FOIT), donde el texto se oculta hasta que se descarga la fuente, o Flash de texto sin estilo (FOUT), donde usa la fuente del sistema alternativo inicialmente y luego la actualiza a la fuente web cuando se descarga. Ninguna opción ha “ganado” realmente porque ninguna es realmente satisfactoria, para ser honesto.

¿No se suponía font-display resolvía esto?

La propiedad font-display para @font-face le dio esa opción al desarrollador web, mientras que anteriormente el navegador decidía eso (IE y Edge favorecían FOUT en el pasado, mientras que los otros navegadores favorecían FOIT). Sin embargo, más allá de eso, realmente no resolvió el problema.

Varios sitios cambiaron a font-display: swap cuando apareció por primera vez, y Google Fonts incluso lo convirtió en el predeterminado en 2019. La idea aquí era que era mejor para el rendimiento mostrar el texto lo más rápido posible , incluso si está en la fuente alternativa, y luego para cambiar la fuente cuando finalmente se descarga.

También apoyé esto en ese entonces, pero me encuentro cada vez más frustrado por el "efecto de hidratación" cuando la fuente web se descarga y los caracteres se expanden (o contraen) debido a las diferencias entre las fuentes. Smashing Magazine, como la mayoría de los editores, utiliza fuentes web y la siguiente captura de pantalla muestra la diferencia entre el renderizado inicial (con las fuentes alternativas) y el renderizado final (con las fuentes web):

Dos capturas de pantalla de un artículo de Smashing Magazine con diferentes fuentes. El texto tiene un tamaño notablemente diferente y puede caber una oración adicional cuando se usan las fuentes web.
Artículo de Smashing Magazine con fuente alternativa y con fuentes web completas. (Vista previa grande)

Ahora, cuando se ponen una al lado de la otra, las fuentes web son considerablemente más agradables y encajan con la marca Smashing Magazine. Pero también vemos que hay bastante diferencia en el diseño del texto con las dos fuentes. Las fuentes son de tamaños muy diferentes y, debido a esto, el contenido de la pantalla cambia. En esta era en la que Core Web Vitals y los cambios acumulativos de diseño se reconocen (¡con razón!) como perjudiciales para los usuarios, font-display: swap es una mala elección debido a eso.

He vuelto a font-display: block en los sitios que cuido, ya que realmente encuentro el cambio de texto bastante discordante y molesto. Si bien es cierto que el block no detendrá los cambios (la fuente aún se representa en texto invisible), al menos los hace menos perceptibles para el usuario. También optimicé la carga de fuentes mediante la precarga de fuentes que he hecho lo más pequeñas posible mediante subconjuntos de fuentes autohospedadas , por lo que los visitantes a menudo veían las fuentes alternativas solo durante un breve período de tiempo. Para mí, el "período de bloqueo" del swap fue demasiado corto y, sinceramente, preferiría esperar un poco más para obtener el renderizado inicial correcto.

¡Más después del salto! Continúe leyendo a continuación ↓

Uso font-display: optional Puede resolver FOIT y FOUT, a un costo

La otra opción es usar font-display: optional . Básicamente, esta opción hace que las fuentes web sean opcionales o, dicho de otro modo, si la fuente no está allí cuando la página la necesita, entonces depende del navegador no cambiarla nunca. Con esta opción, evitamos tanto FOIT como FOUT al usar básicamente solo fuentes que ya se han descargado.

Si la fuente web no está disponible en ese momento, recurrimos a la fuente alternativa, pero la navegación de la siguiente página (o una recarga de esta página) usará la fuente, ya que debería haber terminado de descargarse para entonces. Sin embargo, si la fuente web no es tan importante para el sitio, entonces podría ser una buena idea eliminarla por completo, ¡lo que es incluso mejor para el rendimiento web!

Las primeras impresiones cuentan y tener esa carga inicial sin fuentes web parece demasiado. También pienso, ¡por cierto, sin absolutamente ninguna evidencia que respalde esto! — que le dará a las personas la impresión, quizás inconscientemente, de que algo está "apagado" en el sitio web y puede afectar la forma en que las personas usan el sitio web.

Por lo tanto, todas las opciones de fuentes tienen sus inconvenientes, incluida la opción de no usar fuentes web en absoluto o usar fuentes del sistema (lo cual es limitante, ¡pero quizás no tan limitante como muchos piensan!).

Hacer que su fuente alternativa coincida más con su fuente

El santo grial de la carga de fuentes web ha sido hacer que la fuente alternativa se acerque más a la fuente web real para reducir el cambio notable tanto como sea posible, de modo que el uso del swap tenga menos impacto. Si bien nunca podremos evitar los cambios por completo, podemos hacerlo mejor que en la captura de pantalla anterior. La aplicación Font Style Matcher de Monica Dinculescu se cita a menudo en los artículos de carga de fuentes y ofrece una visión fantástica de lo que debería ser posible aquí. De manera útil, le permite superponer el mismo texto en dos fuentes diferentes para ver cuán diferentes son y ajustar la configuración de la fuente para alinearlas más estrechamente:

Capturas de pantalla de Font Style Matcher que muestran dos conjuntos sobre texto superpuesto uno sobre el otro, con grandes diferencias en la parte superior y un texto muy similar en la parte inferior.
Capturas de pantalla de Font Style Matcher con la misma configuración predeterminada para dos fuentes (arriba) y ajustes ajustados para dar una mejor coincidencia (abajo). (Vista previa grande)

Desafortunadamente, el problema con la coincidencia de estilo de fuente es que no podemos hacer que estos estilos CSS se apliquen solo a las fuentes alternativas, por lo que necesitamos usar JavaScript y la API FontFace.load para aplicar (o revertir) estas diferencias de estilo cuando la web cargas de fuentes .

La cantidad de código no es enorme, pero todavía se siente como un poco más de esfuerzo de lo que debería ser. Aunque hay otras ventajas y posibilidades de usar la API de JavaScript para esto, como lo explicó Zach Leatherman en esta fantástica charla de 2019, puede reducir los reflujos y manejar el modo data-server y prefers-reduced-motion aunque eso (tenga en cuenta sin embargo que ambos han estado expuestos a CSS desde esa charla).

También es más complicado manejar las fuentes almacenadas en caché que ya tenemos, sin mencionar las diferencias en varios estilos alternativos. Aquí en Smashing Magazine, probamos una serie de alternativas para hacer el mejor uso de las fuentes del sistema que han instalado diferentes usuarios y sistemas operativos:

 font-family: Mija,-apple-system,Arial,BlinkMacSystemFont,roboto slab,droid serif,segoe ui,Ubuntu,Cantarell,Georgia,serif;

Saber qué fuente se usa o tener ajustes separados para cada una y asegurarse de que se apliquen correctamente puede volverse bastante complejo rápidamente.

Una mejor solución está llegando

Entonces, esa es una breve puesta al día sobre dónde están las cosas a día de hoy. Sin embargo, algo de humo empieza a aparecer en el horizonte.

Como mencioné anteriormente, el principal problema con la aplicación de las diferencias de estilo de reserva fue agregarlas y luego eliminarlas. ¿Qué pasaría si pudiéramos decirle al navegador que estas diferencias son solo para las fuentes alternativas?

Eso es exactamente lo que hace un nuevo conjunto de descriptores de fuentes que se proponen como parte del Nivel 5 del módulo de fuentes CSS. Estos se aplican a las declaraciones @font-face donde se define la fuente individual.

Simon Hearne ha escrito sobre esta actualización propuesta de la especificación de descriptores de tipo de letra que incluye cuatro nuevos descriptores: ascent-override de descent-override line-gap-override advance-override (desde que se eliminó). Puede jugar con el patio de juegos F-mods que Simon ha creado para cargar sus fuentes personalizadas y alternativas, luego jugar con las anulaciones para obtener una combinación perfecta.

Como escribe Simon, la combinación de estos cuatro descriptores nos permitió anular el diseño de la fuente alternativa para que coincidiera con la fuente web, pero en realidad solo modifican el espaciado y el posicionamiento verticales. Entonces, para el espaciado de caracteres y letras, necesitaremos proporcionar CSS adicional.

Pero las cosas parecen estar cambiando una vez más. Más recientemente, advance-override se eliminó en favor del próximo descriptor size-adjust que nos permite reducir los cambios de diseño al hacer coincidir una fuente alternativa y una fuente web principal a través de un factor de escala para glifos (porcentaje).

¿Como funciona? Digamos que tienes el siguiente CSS:

 @font-face { font-family: 'Lato'; src: url('/static/fonts/Lato.woff2') format('woff2'); font-weight: 400; } h1 { font-family: Lato, Arial, sans-serif; }

Entonces, lo que haría sería crear un @font-face para la fuente alternativa Arial y aplicarle descriptores de ajuste. Entonces obtendrás el siguiente fragmento de CSS:

 @font-face { font-family: 'Lato'; src: url('/static/fonts/Lato.woff2') format('woff2'); font-weight: 400; } @font-face { font-family: "Lato-fallback"; size-adjust: 97.38%; ascent-override: 99%; src: local("Arial"); } h1 { font-family: Lato, Lato-fallback, sans-serif; }

Esto significa que cuando se usa inicialmente el Lato-fallback (ya que Arial es una fuente local y se puede usar de inmediato sin ninguna descarga adicional), las configuraciones size-adjust y ascent-override le permiten acercarse más a la fuente Lato. Es una declaración @font-face adicional para escribir, ¡pero ciertamente mucho más fácil que los aros que tuvimos que atravesar antes!

En general, hay cuatro descriptores principales @font-face incluidos en esta especificación: size-adjust , ascent-override , descent-override y line-gap-override y algunos otros aún se están considerando para subíndices, superíndices y otros casos de uso .

Malte Ubl creó una herramienta muy útil para calcular automáticamente estas configuraciones dadas dos fuentes y un navegador que admita estas nuevas configuraciones (¡más sobre esto en un momento!). Como señala Malte, ¡las computadoras son buenas para ese tipo de cosas! Idealmente, también podríamos exponer estas configuraciones para fuentes comunes a los desarrolladores web, por ejemplo, ¿tal vez dar estas sugerencias en colecciones de fuentes como Google Fonts? Eso sin duda ayudaría a aumentar la adopción.

Ahora, diferentes sistemas operativos pueden tener configuraciones de fuente ligeramente diferentes y lograr que sean exactamente correctas es básicamente una tarea imposible, pero ese no es el objetivo. El objetivo es cerrar la brecha, por lo que usar font-display: swap ya no es una experiencia tan discordante, pero no necesitamos ir a los extremos de fuentes web optional o no.

¿Cuándo podemos empezar a usar esto?

Tres de estas configuraciones ya se han enviado en Chrome desde la versión 87 , aunque el descriptor size-adjust clave aún no está disponible en ningún navegador estable. Sin embargo, Chrome Canary lo tiene, al igual que Firefox detrás de una bandera, por lo que este no es un concepto abstracto y lejano, sino algo que podría aterrizar muy pronto.

Por el momento, la especificación tiene todo tipo de descargos de responsabilidad y advertencias de que aún no está lista para el tiempo real, pero ciertamente parece que está llegando allí. Como siempre, hay un equilibrio entre nosotros, diseñadores y desarrolladores, probándolo y dando retroalimentación, y desalentando su uso, para que la implementación no se atasque porque demasiadas personas terminan usando un borrador anterior.

Chrome ha declarado su intención de hacer size-adjust esté disponible en Chrome 92, cuyo lanzamiento está previsto para el 20 de julio, lo que presumiblemente indica que ya casi está listo.

Entonces, aún no está listo, pero parece que llegará en un futuro muy cercano. Mientras tanto, juegue con la demostración en Chrome Canary y vea si puede acercarse un poco más a solucionar sus problemas de carga de fuentes y el impacto de CLS que causan.