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.
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)
Carga de fuentes en la página turca
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
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-settingslos 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.