Notizbuch · Notiz 002 · Typografie

Zehn Sprachen, drei Schriftdateien

Bei einer Website in zehn Sprachen reißt meist zuerst das Budget für Schriften. Hier nicht. Kyrillische und arabische Zeichen hatten trotzdem ihren Preis. Wir legen ihn offen.

Serhat Belen

Gründer, BLN Global · · 6 Min. Lesezeit

Kurze Antwort

Kämen dieselben drei Schriften von Google Fonts, würde eine türkische Seite 6 Dateien mit 250 KB von zwei externen Quellen laden. Von unserem Server lädt sie 3 Dateien mit 165 KB aus einer Quelle. Den größten Teil sparen wir nicht durch Zeichensätze, sondern indem wir ungenutzte Schriftachsen fest einstellen. Für kyrillische und arabische Zeichen brauchten wir eigene Schriftfamilien. Im Arabischen kommen deshalb einige Symbole aus einer Ersatzschrift.

Die Typografie der Seite lief über drei Familien: Archivo für Überschriften, Instrument Sans für Fließtext, Martian Mono für Zahlen und Labels. Alle drei sind variable Fonts. Mit fünf Sprachen lief alles sauber. Bei zehn Sprachen wuchsen zwei Probleme gleichzeitig: geladene Bytes und abgedeckte Alphabete.

Was wir womit vergleichen

Unsere WOFF2-Dateien mit den rohen TTF-Dateien zu vergleichen, wäre unfair. Der größte Teil des Unterschieds entsteht durch die Komprimierung, nicht durch den Subset. Entscheidend ist die echte Alternative: Wie viel wäre geladen worden, wenn dieselben drei Schriftfamilien von Google Fonts kämen?

Nicht alle neun Dateien laden. Der Browser unicode-range prüft den Bereich und lädt nur die Zeichensätze, die die Seite braucht. Für eine türkische Seite sind das latin + latin-ext pro Schriftfamilie:

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 Türkische Seite lädt: 250 KB (6 Dateien)
Wir haben das Google Fonts CSS geladen, in jedem @font-face-Block unicode-range gelesen und jede Datei einzeln gemessen. Die mit Pfeil lädt eine türkische Seite wirklich.
250 KB / 6 Dateien / 2 externe Origins165 KB / 3 Dateien / eine Origin

Fontlast der türkischen Seite

Wie wir gemessen haben Links steht die Messung oben. Rechts die aus diesem Repository archivo.woff2 + instrument.woff2 + martian.woff2 echte Größe der Dateien auf der Platte.

Neben Bytes sparten wir noch mehr: Wir senkten sechs Requests auf drei und strichen die DNS + TLS-Handshakes zu zwei externen Origins komplett. So schlossen wir das Ressourcenproblem, das den First Paint blockierte in der Notiz zu den letzten 18 Punkten steht dort.

Drei Fallen

Erstens: Im latin-ext-Subset fehlen lateinische Grundzeichen

Beim ersten Versuch haben wir die latin-ext-Datei von Google Fonts geladen und verkleinert. Das Ergebnis enthielt 130 Glyphen, aber keine Ziffern. Der Grund: latin-ext liegt als Ebene über latin, die Zusatz ist ein Set, kein vollständiges Alphabet. Der richtige Weg: Lade die komplette variable Schrift aus dem google/fonts-Repo und zieh das Subset selbst heraus.

Zweitens: Wenn du ungenutzte Achsen nicht festlegst, wächst die Datei auf das Fünffache.

Jede Achse einer variablen Schrift macht die Datei größer. Im Design zählen nur Stärke und Breite. Wenn du die übrigen Achsen nicht auf ihre Standardwerte fixierst, bleiben ihre Daten in der Datei.

tam = {a.axisTag: a.defaultValue for a in t['fvar'].axes if a.axisTag not in eksen} tam.update(eksen) # Achsen außer wght/wdth bleiben beim Standardwert, # sonst wird die Datei fünfmal so groß
Wenn du vor dem Subsetting die Achse festlegst, sparst du mehr Platz als mit dem Subsetting selbst.

Drittens: gvar lädt lazy

Wenn du mit fontTools die Achse festlegst und danach direkt ein Subset ziehen willst KeyError: space subsettet. Der Grund ist Lazy Loading der variablen Glyph-Daten (gvar): Nach dem Festschreiben sieht das Objekt im Speicher konsistent aus, aber der Subsetter liest es nicht. Die Lösung ist umständlich, passt aber in eine Zeile: Datei kurz als TTF speichern, neu öffnen, dann subsetten.

Kyrillisch und Arabisch: was es kostet

Archivo enthält keine kyrillischen Zeichen, Instrument Sans auch nicht. Arabische Zeichen enthält keine der beiden Schriften. Für diese zwei Sprachen musste eine eigene Familie her, und die Auswahl war nicht beliebig.

  • Russisch: Roboto Flex. Nur das passte strukturell: die Breitenachse. Also alle font-variation-settings Die Werte funktionieren unverändert. Eine Datei deckt Überschriften und Fließtext ab. Die russische Seite bleibt kleiner als die Seite mit lateinischer Schrift.
  • Arabisch: Noto Sans Arabic. Der einzige Kandidat mit Breitenachse. Eine Datei mit 144 KB deckt drei Rollen ab, also lädt die arabische Seite weniger als die lateinische.

Der Preis steckt in Noto Sans Arabic und hat diese Glyphen nicht. Auf der arabischen Seite stammen die beiden Zeichen deshalb aus der Ersatzschrift und sehen etwas anders aus als die Zeichen daneben. Statt das zu verstecken, haben wir es in einem CSS-Kommentar festgehalten. Sonst sieht die nächste Person den Unterschied und hält ihn für einen Fehler.

Das Layout von rechts nach links brauchte eigene Anpassungen: Wir drehten die Pfeile um und ersetzten Positionsangaben durch ihre logischen Entsprechungen (margin-inline-start, inset-inline-start), damit dasselbe CSS in beide Richtungen richtig arbeitet.

Eine kleine Einstellung: Warum Martian Mono optional nutzt

Zwei von drei Familien font-display:swap nutzt. Martian Mono optional. Der Grund ist gemessen: Mit swap kommt Martian spät, lässt den Menübutton neu messen und erzeugt 0,015 Layout Shift. Da wir ihn vorladen, ist er praktisch rechtzeitig da. Nur wenn er es nicht schafft, springt die Seite nicht, sondern bleibt bei der Ersatzschrift.

Der gesamte Schriftordner für zehn Sprachen hat 404 KB. Kein Besucher lädt alles. Jede Seite zieht nur die Dateien für ihre eigene Sprache.

Häufige Fragen

Soll ich die Schriften selbst hosten statt Google Fonts zu nutzen?

Bei den Bytes nicht immer, bei den Verbindungen meistens ja. Google Fonts verbindet zu zwei Origins. Jeder neue Origin heißt DNS-Auflösung und TLS-Handshake. Bei uns gemessen: 165 KB / 3 Dateien / ein Origin statt 250 KB / 6 Dateien / 2 Origins.

Was spart mehr, Subsetting oder die Achse festlegen?

Achse fixieren. Jede ungenutzte Achse einer variablen Schrift belegt Platz in der Datei. Wenn du sie nicht fixierst, wächst die Datei um ein Mehrfaches. Subsets kommen danach.

Reicht das latin-ext-Subset für Türkisch?

Nein, latin-ext allein reicht für keine Sprache. latin-ext ist ein zusätzlicher Zeichensatz, der sich mit latin überschneidet. Grundlegende Buchstaben und Ziffern fehlen. Lade die vollständige variable Schrift herunter und erstelle den Subset selbst.

swap oder optional für font-display?

Wenn der Text den Hauptteil der Seite bildet und du die Schrift vorlädst, ist optional sicherer: Kommt sie zu spät, springt die Seite nicht, sie bleibt bei der Ersatzschrift. Bei uns erzeugte swap auf arabischen Seiten einen Layout Shift von 0,287. optional senkte ihn auf null.

Welche Schrift hast du für Arabisch und Russisch gewählt, und warum?

Roboto Flex für Russisch, Noto Sans Arabic für Arabisch. Die Auswahl war keine Geschmacksfrage, sie kam aus der Struktur: Beide haben eine Breitenachse, also kann das bestehende font-variation-settings läuft mit unveränderten Werten.

Quellen

Ähnliche Arbeiten