Reducir el tamaño de la fuente web

Ilya Grigorik
Ilya Grigorik
Jeremy Wagner
Jeremy Wagner

La tipografía es fundamental para lograr un buen nivel de diseño, desarrollo de la marca, legibilidad y accesibilidad. Las fuentes web permiten todo lo anterior y más: el texto admite selección, búsqueda, ampliación y reducción, y admite valores elevados de ppp, lo que permite la representación de texto consistente y bien definido, independientemente del tamaño de la pantalla y la resolución. Las fuentes web son fundamentales para que el diseño, la experiencia de usuario y el rendimiento sean buenos.

La optimización de fuentes web es una pieza fundamental de la estrategia de rendimiento general. Cada fuente es un recurso adicional, y algunas fuentes pueden bloquear la representación del texto; sin embargo, el hecho de que en la página se usen fuentes web no significa que su representación sea lenta. Por el contrario, las fuentes optimizadas, combinadas con una estrategia criteriosa sobre cómo se deben cargar y aplicar en la página, pueden ayudar a reducir el tamaño total de la página y mejorar los tiempos de renderización de la página.

Anatomía de una fuente web

Una fuente web es un conjunto de glifos, y cada glifo es una forma vectorial que describe una letra o un símbolo. En consecuencia, el tamaño de un archivo de fuente específico está determinado por dos variables simples: la complejidad de las rutas de acceso vectoriales de cada glifo y la cantidad de glifos en una fuente determinada. Por ejemplo, Open Sans, que es una de las fuentes web más populares, contiene 897 glifos, entre los que se incluyen caracteres latinos, griegos y cirílicos.

Tabla de glifos de la fuente

Al seleccionar una fuente, es importante considerar los grupos de caracteres admitidos. Si necesitas localizar el contenido de tu página en varios idiomas, debes usar una fuente que pueda proporcionar una apariencia y experiencia uniformes a tus usuarios. Por ejemplo, la familia de fuentes Noto de Google apunta a admitir todos los idiomas del mundo. No obstante, ten en cuenta que el tamaño total del archivo ZIP de Noto, con todos los idiomas incluidos, supera los 1, 1 GB.

En esta publicación, descubrirás cómo reducir el tamaño de archivo entregado de tus fuentes web.

Formatos de fuentes web

En la actualidad, en la Web se usan dos formatos de contenedores de fuentes recomendados:

WOFF y WOFF 2.0 son ampliamente compatibles y son compatibles con todos los navegadores modernos.

  • Proporciona la variante WOFF 2.0 para los navegadores modernos.
  • Si es absolutamente necesario, por ejemplo, si aún necesitas admitir Internet Explorer 11, entrega el WOFF como resguardo.
  • Como alternativa, considera no usar fuentes web para navegadores heredados y recurrir a las fuentes del sistema. Esto también puede tener un mejor rendimiento en dispositivos más antiguos y con más limitaciones.
  • Dado que WOFF y WOFF 2.0 cubren todas las bases para los navegadores modernos y heredados que aún se usan, ya no es necesario usar EOT y TTF, lo que puede generar tiempos de descarga de fuentes web más largos.

Fuentes web y compresión

Tanto WOFF como WOFF 2.0 tienen compresión integrada. La compresión interna de WOFF 2.0 usa Brotli y ofrece hasta un 30% más de compresión que WOFF. Para obtener más información, consulta el informe de evaluación de WOFF 2.0.

Por último, cabe mencionar que algunos formatos de fuente contienen metadatos adicionales, como información de sugerencia de fuentes y interletraje que puede no ser necesaria en algunas plataformas, lo cual permite optimizar aún más el tamaño de archivo. Por ejemplo, Google Fonts ofrece más de 30 variantes optimizadas para cada fuente, y detecta y proporciona automáticamente la variante óptima para cada plataforma y navegador.

Define una familia de fuentes con @font-face

La regla-at @font-face de CSS te permite definir la ubicación de un recurso de fuente determinado, sus características de estilo y los puntos de código Unicode para los que se debe usar. Se puede usar una combinación de estas declaraciones @font-face para construir una "familia de fuentes" que el navegador usará para evaluar los recursos de fuente que debe descargar y aplicar a la página actual.

Considera una fuente variable

Las fuentes variables pueden reducir significativamente el tamaño de archivo de tus fuentes en los casos en que necesites varias variantes de una fuente. En lugar de tener que cargar los estilos normal y en negrita, además de sus versiones en cursiva, puedes cargar un solo archivo que contenga toda la información. Sin embargo, los tamaños de los archivos de fuentes variables serán más grandes que los de una variante de fuente individual, aunque más pequeños que la combinación de muchas variantes. En lugar de una fuente variable grande, puede ser mejor publicar primero las variantes de fuente críticas y descargar otras variantes más adelante.

Ahora, todos los navegadores modernos admiten fuentes variables. Obtén más información en la Introducción a las fuentes variables en la Web.

Selecciona el formato correcto

Cada declaración @font-face proporciona el nombre de la familia de fuentes, que actúa como un grupo lógico compuesto por varias declaraciones, propiedades de fuentes, como el estilo, el grosor y la expansión, y el descriptor src, que especifica una lista priorizada de ubicaciones para el recurso de fuente.

@font-face {
  font-family: 'Awesome Font';
  font-style: normal;
  font-weight: 400;
  src: local('Awesome Font'),
       url('/fonts/awesome.woff2') format('woff2'),
       /* Only serve WOFF if necessary. Otherwise,
          WOFF 2.0 is fine by itself. */
       url('/fonts/awesome.woff') format('woff');
}

@font-face {
  font-family: 'Awesome Font';
  font-style: italic;
  font-weight: 400;
  src: local('Awesome Font Italic'),
       url('/fonts/awesome-i.woff2') format('woff2'),
       url('/fonts/awesome-i.woff') format('woff');
}

Primero, observa que los ejemplos anteriores definen una familia Awesome Font individual con dos estilos (normal y cursiva), y cada uno apunta a un conjunto diferente de recursos de fuente. A su vez, cada descriptor src contiene una lista priorizada de variantes de recursos separadas por comas:

  • La directiva local() te permite hacer referencia a fuentes instaladas localmente, cargarlas y usarlas. Si el usuario ya tiene la fuente instalada en su sistema, se omite por completo la red y es la más rápida.
  • La directiva url() te permite cargar fuentes externas y pueden contener una sugerencia de format() opcional que indique el formato de la fuente a la que se hace referencia en la URL proporcionada.

Cuando el navegador determina que se necesita la fuente, recorre la lista de recursos proporcionada en el orden especificado e intenta cargar el recurso correcto. Por ejemplo, de acuerdo con el ejemplo anterior:

  1. El navegador realiza un diseño de la página y determina las variantes de fuente necesarias para representar en la página el texto especificado. El navegador no descarga las fuentes que no forman parte del CSS Object Model (CSSOM) de la página, ya que no son obligatorias.
  2. Para cada fuente necesaria, el navegador comprueba si la fuente está disponible localmente.
  3. Si la fuente no está disponible localmente, el navegador itera por definiciones externas:
    • Si hay una sugerencia de formato presente, el navegador comprueba si la admite antes de iniciar la descarga. de lo contrario, avanza hacia la siguiente.
    • Si no hay sugerencias de formato, el navegador descarga el recurso.

La combinación de directivas locales y externas con sugerencias de formato adecuadas te permite especificar todos los formatos de fuente disponibles y dejar que el navegador haga el resto. El navegador detecta qué recursos son necesarios y selecciona el formato óptimo.

Subdivisión de Unicode

Además de las propiedades de la fuente, como estilo, grosor y estiramiento, la regla @font-face te permite definir un conjunto de puntos de código Unicode admitidos por cada recurso. Esto te permite dividir una fuente Unicode grande en subconjuntos más pequeños (por ejemplo, los subconjuntos latino, cirílico y griego) y solo descargar los glifos necesarios para representar el texto en una página determinada.

El descriptor unicode-range te permite especificar una lista de valores de intervalo delimitada por comas, en la que cada valor puede presentar una de tres formas diferentes:

  • Punto de código único (por ejemplo, U+416)
  • Amplitud del intervalo (por ejemplo, U+400-4ff): indica los puntos de código inicial y final de un intervalo
  • Intervalo comodín (por ejemplo, U+4??): Los caracteres ? indican dígitos hexadecimales.

Por ejemplo, puedes dividir tu familia Awesome Font en subconjuntos latino y japonés, que el navegador descarga cuando sea necesario:

@font-face {
  font-family: 'Awesome Font';
  font-style: normal;
  font-weight: 400;
  src: local('Awesome Font'),
       url('/fonts/awesome-l.woff2') format('woff2');
  /* Latin glyphs */
  unicode-range: U+000-5FF;
}

@font-face {
  font-family: 'Awesome Font';
  font-style: normal;
  font-weight: 400;
  src: local('Awesome Font'),
       url('/fonts/awesome-jp.woff2') format('woff2');
  /* Japanese glyphs */
  unicode-range: U+3000-9FFF, U+ff??;
}

El uso de subconjuntos del intervalo Unicode y archivos independientes para cada variante estilística nos permite definir una familia de fuentes compuesta cuya descarga es más rápida y más eficiente. Los visitantes solo descargan las variantes y los subconjuntos que necesitan, y no están obligados a descargar subconjuntos que quizá nunca vean ni usen en la página.

Casi todos los navegadores admiten unicode-range. Para lograr la compatibilidad con navegadores anteriores, es posible que debas recurrir a la "subdivisión manual". En este caso, debes recurrir a proporcionar un solo recurso de fuente que contenga todos los subconjuntos necesarios y oculte el resto del navegador. Por ejemplo, si la página solo usa caracteres latinos, puedes eliminar otros glifos y proporcionar ese subconjunto específico como recurso independiente.

  1. Determina qué subconjuntos son necesarios:
    • Si el navegador admite la subdivisión del intervalo Unicode, seleccionará automáticamente el subconjunto adecuado. La página solo deberá proporcionar los archivos del subconjunto y especificar intervalos Unicode apropiados en las reglas @font-face.
    • Si el navegador no admite la subdivisión del intervalo Unicode, la página debe ocultar todos los subconjuntos innecesarios; es decir, el programador debe especificar los subconjuntos necesarios.
  2. Genera subconjuntos de fuentes:
    • Usa la herramienta pyftsubset de código abierto para disponer en subconjuntos y optimizar tus fuentes.
    • Algunos servidores de fuentes, como Google Font, crearán subconjuntos automáticamente de forma predeterminada.
    • Algunos servicios de fuente permiten la subdivisión manual mediante parámetros de consulta personalizados, que puedes usar para especificar manualmente el subconjunto necesario para tu página. Consulta la documentación de tu proveedor de fuentes.

Selección y síntesis de fuentes

Cada familia de fuentes puede estar compuesta por múltiples variantes estilísticas (normal, negrita, cursiva) y múltiples grosores para cada estilo. Cada uno de los cuales, a su vez, puede contener diferentes formas de glifos, como espaciado diferente, ajuste de tamaño diferente o una forma diferente.

Grosores de fuente

En el diagrama anterior, se ilustra una familia de fuentes que ofrece tres tamaños de negrita diferentes:

  • 400 (normal).
  • 700 (negrita).
  • 900 (extranegrita).

Todas las demás variantes intermedias (indicadas en gris) son asignadas automáticamente por el navegador a la variante más cercana.

Cuando se especifica un grosor para el que no existe una fuente, se usa una fuente con un grosor aproximado. En general, los espesores en negrita se asignan a fuentes con espesores más gruesos, y los espesores finos se asignan a fuentes con espesores más delgados.

Algoritmo de coincidencia de fuentes CSS

Se aplica una lógica similar a las variantes de cursiva. El diseñador de fuentes controla las variantes que producirá y tú controlas las que usarás en la página. Dado que cada variante supone una descarga individual, se recomienda que el número de variantes sea reducido. Por ejemplo, puedes definir dos variantes en negrita para la familia Awesome Font:

@font-face {
  font-family: 'Awesome Font';
  font-style: normal;
  font-weight: 400;
  src: local('Awesome Font'),
       url('/fonts/awesome-l.woff2') format('woff2');
  /* Latin glyphs */
  unicode-range: U+000-5FF;
}

@font-face {
  font-family: 'Awesome Font';
  font-style: normal;
  font-weight: 700;
  src: local('Awesome Font'),
       url('/fonts/awesome-l-700.woff2') format('woff2');
  /* Latin glyphs */
  unicode-range: U+000-5FF;
}

En el ejemplo anterior, se declara que la familia Awesome Font está compuesta por dos recursos que abarcan el mismo conjunto de glifos latinos (U+000-5FF), pero estos ofrecen dos "espesores" diferentes: normal (400) y negrita (700). Sin embargo, ¿qué sucede si en una de tus reglas CSS se especifica un grosor de fuente diferente o se establece la propiedad font-style en italic?

  • Si no hay una coincidencia de fuente exacta disponible, el navegador usa la más cercana.
  • Si no se encuentra una coincidencia estilística (por ejemplo, en el caso anterior no se declararon variantes de cursiva), el navegador sintetiza su propia variante de fuente.
Síntesis de fuentes

En el ejemplo anterior, se ilustra la diferencia entre los resultados de la fuente real frente a la fuente sintetizada para Open Sans. Todas las variantes sintetizadas se generan a partir de una fuente individual con un grosor de 400. Como puedes ver, existe una diferencia notoria en los resultados. No se especifican los detalles sobre cómo generar las variantes negrita y oblicua. Por lo tanto, los resultados varían de un navegador a otro y también dependen en gran medida de la fuente.

Lista de tareas para optimizar el tamaño de la fuente web

  • Audita y controla el uso de fuentes: no uses demasiadas en tus páginas y, para cada una, minimiza la cantidad de variantes empleadas. Esto ayuda a proporcionar una experiencia más uniforme y rápida para tus usuarios.
  • Evita los formatos heredados si es posible: Los formatos EOT, TTF y WOFF son más grandes que WOFF 2.0. EOT y TTF son formatos estrictamente innecesarios, mientras que WOFF puede ser aceptable si necesitas admitir Internet Explorer 11. Si solo te orientas a navegadores modernos, la opción más simple y con mejor rendimiento es usar solo WOFF 2.0.
  • Subdivide tus recursos de fuentes: Muchas fuentes pueden subdividirse en diferentes intervalos Unicode para proporcionar solo los glifos necesarios para una página determinada. Esto reduce el tamaño del archivo y mejora la velocidad de descarga del recurso. No obstante, al definir subconjuntos, procura aplicar optimizaciones para la reutilización de las fuentes; por ejemplo, no te convendrá descargar un conjunto de caracteres diferentes y superpuestos en cada página. Una buena práctica es la disposición en subconjuntos según el tipo de fuente; por ejemplo, latino y cirílico.
  • Prioriza local() en tu lista src: Si colocas local('Font Name') en primer lugar en la lista src, se garantiza que no se realicen solicitudes HTTP en las fuentes que ya están instaladas.
  • Usa Lighthouse para probar la compresión de texto.

Efectos en el procesamiento de imagen con contenido más grande (LCP) y el cambio de diseño acumulado (CLS)

Según el contenido de tu página, los nodos de texto se pueden considerar candidatos para el Largest Contentful Paint (LCP). Por lo tanto, es fundamental que sigas los consejos de este artículo para asegurarte de que tus fuentes web sean lo más pequeñas posible, de modo que los usuarios vean el texto de tu página lo antes posible.

Si te preocupa que, a pesar de tus esfuerzos de optimización, el texto de la página tarde demasiado en aparecer debido a un gran recurso de fuente web, la propiedad font-display tiene varios parámetros de configuración que pueden ayudarte a evitar el texto invisible mientras se descarga una fuente. Sin embargo, usar el valor swap puede causar cambios de diseño significativos que afecten el Cambio de diseño acumulativo (CLS) de tu sitio. Considera usar los valores optional o fallback si es posible.

Si tus fuentes web son fundamentales para tu desarrollo de la marca y, por extensión, para la experiencia del usuario, considera precargar las fuentes para que el navegador tenga una ventaja cuando las solicite. Esto puede reducir el período de intercambio si usas font-display: swap o el período de bloqueo si no usas font-display.