Cuaderno · Nota 002 · Tipografía

Diez idiomas, tres archivos de fuente

Al publicar un sitio en diez idiomas, el presupuesto de fuentes suele ser lo primero que salta por los aires. Esta vez no. Pero los alfabetos cirílico y árabe tuvieron otro coste, y lo mostramos.

Serhat Belen

Fundador, BLN Global · · 6 min

Respuesta breve

Con esas tres fuentes desde Google Fonts, una página en turco descargaría 6 archivos y 250 KB desde dos orígenes externos. Desde nuestro servidor descarga 3 archivos y 165 KB desde un solo origen. Casi todo el ahorro viene de fijar los ejes sin usar, no de reducir caracteres. El cirílico y el árabe exigieron familias distintas. En árabe, algunos símbolos recurren a una fuente de reserva.

La tipografía del sitio usaba tres familias: Archivo para titulares, Instrument Sans para texto, Martian Mono para cifras y etiquetas. Las tres eran variables. Con cinco idiomas iba bien. Al subir a diez, crecieron dos problemas a la vez: bytes descargados y cobertura de alfabetos.

Qué comparamos con qué

Comparar los archivos TTF originales con los WOFF2 que publicamos sería engañoso. Gran parte de la diferencia viene de la compresión, no del subconjunto. La comparación útil es con la alternativa real: cuánto se descargaría si esas tres familias llegaran desde Google Fonts.

No se bajan los nueve archivos. El navegador unicode-range consulta el campo y carga solo los subconjuntos que necesita la página. En turco, eso significa latin + latin-ext por familia:

latin 88.0 KB <- latin-ext 83.8 KB <- vietnamese 33.6 KB latin 29.2 KB <- latin-ext 10.8 KB <- latin 23.0 KB <- latin-ext 15.5 KB <- cyrillic 10.3 KB cyrillic-ext 3.1 KB Lo que descargará la página en turco: 250 KB (6 archivos)
Descargamos el CSS de Google Fonts, leímos el unicode-range de cada bloque @font-face y pesamos los archivos uno a uno. Los marcados con flecha son los que de verdad baja una página en turco.
250 KB / 6 archivos / 2 orígenes externos165 KB / 3 archivos / un solo origen

Carga de fuentes en la página turca

Cómo lo medimos A la izquierda, la medición anterior. A la derecha, la de este repositorio archivo.woff2 + instrument.woff2 + martian.woff2 tamaño real de los archivos en disco.

Junto a los bytes ganamos dos cosas más: 6 solicitudes bajaron a 3 y desapareció por completo la negociación DNS + TLS con dos orígenes externos. Cómo cerramos el problema del recurso que bloqueaba el primer pintado en la nota de los últimos 18 puntos se cuenta.

Tres trampas

Uno: el subconjunto latin-ext no contiene las letras latinas básicas

En el primer intento descargamos el archivo latin-ext de Google Fonts y lo recortamos. El resultado tenía 130 glifos, pero ninguna cifra. La razón era sencilla: latin-ext es una capa que se añade a latin, no un extra es un conjunto, no un alfabeto completo. La vía correcta: baja la tipografía variable completa del repositorio google/fonts y saca tú el subconjunto.

Dos: si no fijas los ejes sin usar, el archivo pesa cinco veces más

Cada eje de una tipografía variable pesa dentro del archivo. El diseño solo usa grosor y ancho. Si no fijas los demás ejes en sus valores por defecto, sus datos se quedan dentro.

tam = {a.axisTag: a.defaultValue for a in t['fvar'].axes if a.axisTag not in eksen} tam.update(eksen) # Los ejes distintos de wght/wdth se fijan en su valor predeterminado, # de lo contrario el archivo pesa cinco veces más
Fijar el eje antes de crear el subconjunto ahorra más que el propio subconjunto.

Tres: gvar carga en diferido

al fijar el eje con fontTools e intentar crear el subconjunto directamente KeyError: space se obtiene. La causa está en la carga diferida de los datos de glifos variables (gvar): después de fijar los ejes, el objeto parece coherente en memoria, pero la herramienta de subconjuntos no lo lee. La salida es enrevesada, aunque cabe en una línea: guarda el archivo como TTF temporal, ábrelo de nuevo y luego extrae el subconjunto.

Cirílico y árabe: el coste

Archivo no tiene cirílico. Instrument Sans tampoco. Ninguna incluye árabe. Tocaba elegir otra familia para esos dos idiomas, y no la elegimos al azar.

  • Ruso: Roboto Flex. La única coincidencia estructural era esa: tiene eje de anchura. Así que todos los font-variation-settings los valores funcionan sin tocar nada. Un archivo sirve para títulos y texto. La página rusa pesa menos que la latina.
  • Árabe: Noto Sans Arabic. El único candidato con eje de ancho. Un solo archivo de 144 KB cubre tres roles, así que la página en árabe descarga menos que la página latina.

El coste está ahí: en Noto Sans Arabic y no incluye esos símbolos. En la página en árabe, ambos signos proceden de la tipografía de reserva y se ven un poco distintos a los caracteres contiguos. En vez de ocultarlo, lo explicamos en un comentario del CSS. Así, quien lo vea después no lo confundirá con un error.

El diseño de derecha a izquierda requiere trabajo aparte: invertimos las flechas y sustituimos las propiedades de posición por sus equivalentes lógicos (margin-inline-start, inset-inline-start), así el mismo CSS funciona bien en las dos direcciones.

Un pequeño ajuste: por qué Martian Mono usa optional

Dos de tres familias font-display:swap usa. Martian Mono optional. La razón está medida: con swap, Martian llegaba tarde, obligaba a medir de nuevo el botón del menú y generaba un salto de diseño de 0,015. Como se precarga, en la práctica llega a tiempo. Si no llega, la página no se mueve y se queda con la fuente de respaldo.

La carpeta de fuentes para diez idiomas ocupa 404 KB. Nadie la descarga entera. Cada página carga solo los archivos de su idioma.

Preguntas frecuentes

¿Debería alojar las fuentes en mi servidor en vez de usar Google Fonts?

En bytes, no siempre. En conexiones, casi siempre sí. Google Fonts conecta con dos orígenes distintos, y cada origen nuevo exige DNS y negociación TLS. Nuestra medición quedó así: 250 KB / 6 archivos / 2 orígenes frente a 165 KB / 3 archivos / un solo origen.

¿Qué ahorra más, crear subconjuntos o fijar el eje?

Fija los ejes. Cada eje que no usas en una tipografía variable ocupa sitio en el archivo. Si no lo fijas, el archivo se multiplica. Luego ya recortas el subconjunto.

¿Basta el subconjunto latin-ext para el turco?

No. Por sí solo no basta para ningún idioma. latin-ext es un conjunto adicional que se superpone a latin. No contiene las letras básicas ni los números. Descarga la tipografía variable completa y genera tú el subconjunto.

¿swap u optional para font-display?

Si el texto forma el cuerpo de la página y la fuente está precargada, optional es más seguro: si llega tarde, la página no se mueve y se queda con la de reserva. Con swap, nuestras páginas en árabe generaban 0,287 de desplazamiento. optional lo dejó en 0.

¿Qué fuente elegiste para árabe y ruso, y por qué?

Roboto Flex para ruso, Noto Sans Arabic para árabe. No fue una decisión estética, sino de estructura: las dos tienen eje de ancho, así que el CSS actual font-variation-settings funciona sin tocar los valores.

Fuentes

Trabajos relacionados