13 Min. Lesezeit

Web-Fonts: Performance, Variable Fonts & Self-Hosting

Von websicheren Fonts über @font-face bis zu Variable Fonts – moderne Strategien für performante und DSGVO-konforme Web-Typografie.

css

Typografie ist ein zentrales Element guten Webdesigns – und gleichzeitig einer der größten Performance-Killer. Eine einzige schlecht eingebundene Schrift kann die Ladezeit um mehrere Sekunden erhöhen, Layout-Shifts verursachen und sogar rechtliche Probleme auslösen (DSGVO). Dieser Artikel zeigt, wie man Web-Fonts richtig einsetzt: von der Auswahl über die Optimierung bis zum DSGVO-konformen Self-Hosting.

Was passiert wenn ein Font lädt?

Bevor wir über Strategien sprechen, müssen wir verstehen, was beim Laden einer Web-Font passiert:

Browser findet @font-face Deklaration
          │
          ▼
Font wird noch nicht heruntergeladen!
(Browser wartet bis Text den Font tatsächlich nutzt)
          │
          ▼
Erstes Element mit font-family: 'CustomFont' wird gerendert
          │
          ▼
Browser startet Download der .woff2 Datei
          │
          ├─── Während des Downloads: ───┐
          │    FOIT oder FOUT            │
          │    (je nach font-display)    │
          │                              │
          ▼                              ▼
    Font geladen!              Timeout (3s Standard)
    Text wird neu gerendert    → Fallback-Font bleibt

FOIT = Flash of Invisible Text → Text ist unsichtbar während der Font lädt FOUT = Flash of Unstyled Text → Fallback-Font wird kurz angezeigt, dann springt es

Beides ist schlecht für die User Experience, aber steuerbar.

Websichere Schriften (System Fonts)

Als websichere Schriften gelten Fonts, die auf den meisten Betriebssystemen vorinstalliert sind. Sie müssen nicht heruntergeladen werden.

┌─────────────────┬─────────┬───────┬───────┬─────┬─────────┐
│ Font            │ Windows │ macOS │ Linux │ iOS │ Android │
├─────────────────┼─────────┼───────┼───────┼─────┼─────────┤
│ Arial           │ ✅      │ ✅    │ ✅    │ ✅  │ ❌      │
│ Georgia         │ ✅      │ ✅    │ ⚠️    │ ✅  │ ❌      │
│ Times New Roman │ ✅      │ ✅    │ ⚠️    │ ✅  │ ❌      │
│ Verdana         │ ✅      │ ✅    │ ⚠️    │ ✅  │ ❌      │
│ Courier New     │ ✅      │ ✅    │ ✅    │ ✅  │ ❌      │
│ Trebuchet MS    │ ✅      │ ✅    │ ⚠️    │ ✅  │ ❌      │
│ Tahoma          │ ✅      │ ✅    │ ⚠️    │ ✅  │ ❌      │
└─────────────────┴─────────┴───────┴───────┴─────┴─────────┘

Problem: Android hat keine der klassischen websicheren Fonts vorinstalliert. Stattdessen nutzt es Roboto als System-Font. iOS verwendet San Francisco.

Der moderne System Font Stack

Statt einzelner Fonts empfiehlt sich ein System Font Stack, der die native Schrift des jeweiligen OS nutzt:

/* System UI Font Stack – die beste Performance */
body {
  font-family:
    system-ui,                /* Moderne Browser */
    -apple-system,            /* Safari (ältere Versionen) */
    BlinkMacSystemFont,       /* Chrome auf macOS */
    "Segoe UI",               /* Windows */
    Roboto,                   /* Android */
    "Helvetica Neue",         /* macOS Fallback */
    Arial,                    /* Universeller Fallback */
    sans-serif;               /* Generischer Fallback */
}

/* Monospace Stack für Code */
code, pre {
  font-family:
    ui-monospace,             /* Moderne Browser */
    SFMono-Regular,           /* macOS */
    "SF Mono",                /* macOS */
    Menlo,                    /* macOS Fallback */
    Consolas,                 /* Windows */
    "Liberation Mono",        /* Linux */
    "Courier New",            /* Universell */
    monospace;                /* Generisch */
}

/* Serif Stack */
.prose {
  font-family:
    "Iowan Old Style",        /* macOS */
    "Palatino Linotype",      /* Windows */
    "URW Palladio L",         /* Linux */
    Georgia,                  /* Universell */
    serif;
}

Was bekommt der Nutzer zu sehen?

┌─────────────┬────────────────────────┐
│ System      │ system-ui zeigt        │
├─────────────┼────────────────────────┤
│ macOS       │ San Francisco          │
│ Windows 11  │ Segoe UI Variable      │
│ Windows 10  │ Segoe UI               │
│ Android     │ Roboto                 │
│ Ubuntu      │ Ubuntu Sans            │
│ iOS         │ San Francisco          │
└─────────────┴────────────────────────┘

Vorteile von System Fonts:

  • Keine externen Fonts laden → beste Performance (0 KB zusätzlich)
  • Native Look & Feel → die Seite fühlt sich heimisch an
  • Keine DSGVO-Probleme → keine externen Requests
  • Kein FOUT/FOIT → Text ist sofort sichtbar

Wann System Fonts die richtige Wahl sind:

  • Performance ist die oberste Priorität
  • Die Seite soll sich wie eine native App anfühlen
  • Man braucht keine spezielle Marken-Typografie

@font-face – Custom Fonts einbinden

Für individuelle Typografie nutzt man @font-face. Das ist die Basis für jede Custom-Font-Einbindung:

/* Einfachste Form */
@font-face {
  font-family: 'Inter';
  src: url('/fonts/Inter.woff2') format('woff2');
  font-display: swap;
}

/* Vollständig mit Varianten */
@font-face {
  font-family: 'Inter';
  src: url('/fonts/Inter-Regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Inter';
  src: url('/fonts/Inter-Medium.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Inter';
  src: url('/fonts/Inter-Bold.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Inter';
  src: url('/fonts/Inter-Italic.woff2') format('woff2');
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

Font-Formate

┌─────────┬──────────┬──────────┬───────────────────────────────┐
│ Format  │ Support  │ Größe    │ Empfehlung                    │
├─────────┼──────────┼──────────┼───────────────────────────────┤
│ WOFF2   │ 98%+     │ Kleinste │ ✅ Der Standard               │
│ WOFF    │ 99%+     │ Klein    │ Nur als Fallback für IE11     │
│ TTF/OTF │ 99%+     │ Groß     │ ❌ Nur für lokale Anwendungen │
│ EOT     │ IE only  │ Mittel   │ ❌ Veraltet                   │
│ SVG     │ ❌       │ Riesig   │ ❌ Veraltet                   │
└─────────┴──────────┴──────────┴───────────────────────────────┘

2024 reicht WOFF2 allein aus. Alle modernen Browser (Chrome, Firefox, Safari, Edge) unterstützen es. WOFF2 nutzt Brotli-Kompression und ist ~30% kleiner als WOFF.

/* Früher: Bulletproof @font-face (für IE6-11) */
@font-face {
  font-family: 'MyFont';
  src: url('font.eot');
  src: url('font.eot?#iefix') format('embedded-opentype'),
       url('font.woff2') format('woff2'),
       url('font.woff') format('woff'),
       url('font.ttf') format('truetype');
}

/* Heute: Eine Zeile reicht */
@font-face {
  font-family: 'MyFont';
  src: url('font.woff2') format('woff2');
  font-display: swap;
}

font-display – Ladestrategien

Die font-display Property steuert das Verhalten während des Font-Ladens. Sie ist die wichtigste Eigenschaft für Web-Font-Performance.

Die fünf Optionen

┌──────────┬─────────────────────┬───────────────┬──────────────────────────────────┐
│ Wert     │ Block-Periode       │ Swap-Periode  │ Beste Nutzung                    │
├──────────┼─────────────────────┼───────────────┼──────────────────────────────────┤
│ auto     │ Browser entscheidet │ –             │ ❌ Nicht empfohlen               │
│ block    │ 3s unsichtbar       │ Unbegrenzt    │ Icon-Fonts, kritische Headlines  │
│ swap     │ Sofort Fallback     │ Unbegrenzt    │ ✅ Body Text, Navigation         │
│ fallback │ 100ms Block         │ 3s            │ Performance-kritisch             │
│ optional │ 100ms Block         │ Keine         │ Schlechte Verbindungen, optional │
└──────────┴─────────────────────┴───────────────┴──────────────────────────────────┘

Visualisierung

font-display: block
┌──────────────────┬──────────────────────────────┐
│ ████ Unsichtbar  │ Custom Font (oder Fallback)   │
│ (bis zu 3s)      │                               │
└──────────────────┴──────────────────────────────┘

font-display: swap
┌──┬─────────────────────────────────────────────┐
│  │ Fallback Font → Springt zu Custom Font       │
│  │ (Sofort lesbar, dann Wechsel = FOUT)         │
└──┴─────────────────────────────────────────────┘

font-display: fallback
┌───┬────────────┬────────────────────────────────┐
│   │ Fallback   │ Custom Font (wenn schnell genug)│
│   │ (100ms     │ Sonst bleibt Fallback           │
│   │  Block)    │                                 │
└───┴────────────┴────────────────────────────────┘

font-display: optional
┌───┬──────────────────────────────────────────────┐
│   │ Fallback oder Custom Font                     │
│   │ (Browser entscheidet basierend auf            │
│   │  Verbindungsgeschwindigkeit)                  │
└───┴──────────────────────────────────────────────┘

Empfohlene Strategie

/* Body-Text: Immer lesbar, Font nachträglich laden */
@font-face {
  font-family: 'Body';
  src: url('/fonts/body.woff2') format('woff2');
  font-display: swap;
}

/* Headlines: Nur wenn gecached (kein Flash) */
@font-face {
  font-family: 'Headline';
  src: url('/fonts/headline.woff2') format('woff2');
  font-display: optional;
}

/* Icon-Font: Muss auf den Font warten */
@font-face {
  font-family: 'Icons';
  src: url('/fonts/icons.woff2') format('woff2');
  font-display: block;
}

Variable Fonts – Eine Datei, alle Varianten

Variable Fonts sind die bedeutendste Entwicklung in der Web-Typografie der letzten Jahre. Statt separate Dateien für jedes Gewicht und jeden Stil enthält ein Variable Font alle Varianten in einer einzigen Datei.

Traditionell vs. Variable Font

Traditionell (6 Dateien):
├── Inter-Light.woff2      (~25KB)
├── Inter-Regular.woff2    (~25KB)
├── Inter-Medium.woff2     (~26KB)
├── Inter-SemiBold.woff2   (~26KB)
├── Inter-Bold.woff2       (~26KB)
└── Inter-Black.woff2      (~27KB)
    Gesamt: ~155KB

Variable Font (1 Datei):
└── Inter-Variable.woff2   (~100KB)
    Gesamt: ~100KB + unendliche Zwischenwerte!

Einbindung

@font-face {
  font-family: 'Inter';
  src: url('/fonts/Inter-VariableFont.woff2') format('woff2');
  font-weight: 100 900;  /* Gesamter Bereich */
  font-style: oblique 0deg 10deg;
  font-display: swap;
}

/* Nutzung mit beliebigen Zwischenwerten */
.thin       { font-weight: 100; }
.extralight { font-weight: 200; }
.light      { font-weight: 300; }
.regular    { font-weight: 400; }
.medium     { font-weight: 500; }
.semibold   { font-weight: 600; }
.bold       { font-weight: 700; }
.extrabold  { font-weight: 800; }
.black      { font-weight: 900; }

/* Auch Zwischenwerte möglich! */
.custom1    { font-weight: 350; }
.custom2    { font-weight: 450; }
.custom3    { font-weight: 650; }

Achsen (Axes)

Variable Fonts haben Achsen – steuerbare Eigenschaften. Es gibt Standard-Achsen und Custom-Achsen:

.text {
  /* Standard-Achsen (mit CSS-Properties steuerbar) */
  font-weight: 425;           /* wght – Gewicht */
  font-stretch: 110%;         /* wdth – Breite */
  font-style: oblique 12deg;  /* slnt – Neigung */

  /* Custom-Achsen (über font-variation-settings) */
  font-variation-settings:
    'wght' 425,
    'wdth' 110,
    'CASL' 0.5,  /* Casual – custom */
    'MONO' 1,    /* Monospace – custom */
    'CRSV' 1;    /* Cursive – custom */
}
┌──────────────┬──────────┬──────────────────────────────────┐
│ Achse        │ CSS Tag  │ Beschreibung                     │
├──────────────┼──────────┼──────────────────────────────────┤
│ Weight       │ wght     │ Schriftstärke (100-900)          │
│ Width        │ wdth     │ Schriftbreite (75%-125%)         │
│ Slant        │ slnt     │ Neigung (-90deg bis 90deg)       │
│ Italic       │ ital     │ Kursiv (0 oder 1)                │
│ Optical Size │ opsz     │ Optische Größenanpassung         │
├──────────────┼──────────┼──────────────────────────────────┤
│ Casual       │ CASL     │ Custom: Casual-Style (Recursive) │
│ Monospace    │ MONO     │ Custom: Monospace (Recursive)    │
│ Grade        │ GRAD     │ Custom: Feinabstufung            │
└──────────────┴──────────┴──────────────────────────────────┘

Animationen mit Variable Fonts

/* Font-Weight Animation – sanfter Übergang */
@keyframes breathe {
  0%, 100% { font-weight: 300; }
  50%      { font-weight: 700; }
}

.breathing-text {
  animation: breathe 3s ease-in-out infinite;
}

/* Hover-Effekt */
.interactive-text {
  font-weight: 400;
  transition: font-weight 0.3s ease;
}

.interactive-text:hover {
  font-weight: 700;
}

Beliebte Variable Fonts

┌───────────────┬───────────────────────┬────────┬──────────┐
│ Font          │ Achsen                │ Lizenz │ Einsatz  │
├───────────────┼───────────────────────┼────────┼──────────┤
│ Inter         │ wght, slnt            │ OFL    │ UI/Web   │
│ Fira Code     │ wght                  │ OFL    │ Code     │
│ Roboto Flex   │ wght, wdth, slnt, ... │ OFL    │ UI       │
│ Source Sans 3 │ wght, wdth            │ OFL    │ UI       │
│ Recursive     │ wght, CASL, MONO, slnt│ OFL    │ Code/UI  │
│ JetBrains Mono│ wght                  │ OFL    │ Code     │
│ Fraunces      │ wght, opsz, SOFT, WONK│OFL     │ Display  │
└───────────────┴───────────────────────┴────────┴──────────┘

Links:

Performance-Optimierung

1. Preload kritischer Fonts

<head>
  <!-- Kritischen Font vorladen – startet Download sofort! -->
  <link rel="preload"
        href="/fonts/body.woff2"
        as="font"
        type="font/woff2"
        crossorigin>

  <!-- Maximal 1-2 Fonts preloaden, sonst blockiert es andere Ressourcen -->

  <!-- Preconnect für externe Quellen -->
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
</head>

Wichtig: crossorigin ist immer nötig bei Font-Preloads, auch bei Same-Origin! Ohne dieses Attribut wird der Font doppelt heruntergeladen.

2. Font Subsetting

Die mächtigste Optimierung: Entferne alle Zeichen aus der Font-Datei, die du nicht brauchst.

# Mit pyftsubset (fonttools)
pip install fonttools brotli

# Nur lateinische Zeichen + deutsche Umlaute + Sonderzeichen
pyftsubset Inter-Variable.woff2 \
  --unicodes="U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,\
              U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,\
              U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,\
              U+FEFF,U+FFFD" \
  --flavor=woff2 \
  --output-file=Inter-Variable-latin.woff2
Ergebnis:
┌─────────────────────────┬────────────────┐
│ Datei                   │ Größe          │
├─────────────────────────┼────────────────┤
│ Inter-Variable.woff2    │ ~300KB         │
│ Inter-Variable-latin    │ ~70KB  (-77%)  │
│ Inter-Variable-de       │ ~35KB  (-88%)  │
└─────────────────────────┴────────────────┘

Unicode-Range für granulares Laden

/* Nur Lateinisch laden (die meisten Besucher) */
@font-face {
  font-family: 'Inter';
  src: url('/fonts/Inter-latin.woff2') format('woff2');
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC,
    U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC,
    U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* Kyrillisch nur wenn benötigt (wird nur geladen wenn
   kyrillische Zeichen auf der Seite vorkommen) */
@font-face {
  font-family: 'Inter';
  src: url('/fonts/Inter-cyrillic.woff2') format('woff2');
  font-display: swap;
  unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

3. Fallback-Font metrisch anpassen

Der Hauptgrund für Layout-Shifts: Der Fallback-Font hat andere Metriken als der Custom Font. Mit CSS Override-Descriptors kann man das beheben:

/* Custom Font */
@font-face {
  font-family: 'Inter';
  src: url('/fonts/Inter.woff2') format('woff2');
  font-display: swap;
}

/* Metrisch angepasster Fallback */
@font-face {
  font-family: 'Inter-fallback';
  src: local('Arial');
  size-adjust: 107%;
  ascent-override: 90%;
  descent-override: 22%;
  line-gap-override: 0%;
}

body {
  font-family: 'Inter', 'Inter-fallback', sans-serif;
}

Was die Override-Descriptors bewirken:

Ohne Anpassung:                 Mit Anpassung:
┌─────────────────────┐         ┌─────────────────────┐
│ Lorem ipsum dolor   │         │ Lorem ipsum dolor   │
│ sit amet, cons.     │ SHIFT   │ sit amet, consec.   │
│ adipiscing elit.    │  →→→    │ adipiscing elit.    │
│ Sed do eiusmod      │         │ Sed do eiusmod      │
└─────────────────────┘         └─────────────────────┘
    Arial (Fallback)                Inter (Custom)

→ Der Text "springt" beim Font-Wechsel

Ohne Anpassung (Shift):            Mit size-adjust (kein Shift):
┌─────────────────────┐         ┌─────────────────────┐
│ Lorem ipsum dolor   │         │ Lorem ipsum dolor   │
│ sit amet, consec.   │  ═══   │ sit amet, consec.   │
│ adipiscing elit.    │         │ adipiscing elit.    │
│ Sed do eiusmod      │         │ Sed do eiusmod      │
└─────────────────────┘         └─────────────────────┘
   Arial (angepasst)                Inter (geladen)

→ Kein Sprung! Die Metriken stimmen überein

4. Automatisches Fallback-Matching mit Next.js

// next.config.js – Next.js macht das automatisch!
const { Inter } = require('next/font/google');

const inter = Inter({
  subsets: ['latin'],
  display: 'swap',
  adjustFontFallback: true, // Automatische Metrik-Anpassung
});

Self-Hosting vs. CDN (DSGVO)

Google Fonts & DSGVO

Das LG München hat 2022 entschieden: Das Einbinden von Google Fonts über deren CDN ist in Deutschland nicht DSGVO-konform, weil IP-Adressen an Google-Server (in den USA) übertragen werden. Das Urteil (Az. 3 O 17493/20) verhängte 100€ Schmerzensgeld pro Besucher.

<!-- ❌ NICHT DSGVO-konform (direkter Google-Request) -->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700"
      rel="stylesheet">

<!-- ❌ AUCH NICHT OK (CSS importiert Font-Dateien von Google-Servern) -->
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter');
</style>

<!-- ✅ DSGVO-konform: Self-Hosting -->
<style>
@font-face {
  font-family: 'Inter';
  src: url('/fonts/Inter-Variable.woff2') format('woff2');
  font-weight: 100 900;
  font-display: swap;
}
</style>

Fonts selbst hosten – Schritt für Schritt

1. Font herunterladen:

2. Projektstruktur:

/
├── static/
│   └── fonts/
│       ├── Inter-Variable.woff2    # Variable Font (alle Gewichte)
│       └── FiraCode-Variable.woff2 # Code-Font
├── assets/
│   └── scss/
│       └── _fonts.scss             # @font-face Deklarationen

3. @font-face deklarieren:

/* _fonts.scss */
@font-face {
  font-family: 'Inter';
  src: url('/fonts/Inter-Variable.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Fira Code';
  src: url('/fonts/FiraCode-Variable.woff2') format('woff2');
  font-weight: 300 700;
  font-display: swap;
}

4. In HTML preloaden:

<head>
  <link rel="preload" href="/fonts/Inter-Variable.woff2"
        as="font" type="font/woff2" crossorigin>
</head>

CDN-Alternative: Bunny Fonts

Für wer trotzdem ein CDN nutzen möchte, gibt es DSGVO-konforme Alternativen:

<!-- Bunny Fonts – EU-basiertes CDN, DSGVO-konform -->
<link href="https://fonts.bunny.net/css?family=inter:400,700"
      rel="stylesheet">

Bunny Fonts ist ein europäisches CDN das keine personenbezogenen Daten speichert.

Vollständiges Beispiel: Optimierte Font-Einbindung

/* fonts.css – Best Practice 2024 */

/* === Variable Fonts mit Subsetting === */

/* Inter – UI/Body Font */
@font-face {
  font-family: 'Inter';
  src: url('/fonts/Inter-Variable-latin.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC,
    U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC,
    U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* Fira Code – Code/Monospace Font */
@font-face {
  font-family: 'Fira Code';
  src: url('/fonts/FiraCode-Variable.woff2') format('woff2');
  font-weight: 300 700;
  font-display: swap;
}

/* === Metrisch angepasster Fallback === */
@font-face {
  font-family: 'Inter-fallback';
  src: local('Arial');
  size-adjust: 107%;
  ascent-override: 90%;
  descent-override: 22%;
  line-gap-override: 0%;
}

/* === CSS Custom Properties === */
:root {
  --font-sans: 'Inter', 'Inter-fallback', system-ui, -apple-system, sans-serif;
  --font-mono: 'Fira Code', ui-monospace, SFMono-Regular, monospace;
}

/* === Anwendung === */
body {
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 1rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3 {
  font-weight: 700;
  line-height: 1.2;
}

code, pre {
  font-family: var(--font-mono);
  font-weight: 450;
  font-variation-settings: 'wght' 450;
}

/* Ligatures für Code-Fonts */
code {
  font-variant-ligatures: common-ligatures;
}
<!-- head.html – Optimiertes Loading -->
<head>
  <!-- Preload nur den wichtigsten Font -->
  <link rel="preload"
        href="/fonts/Inter-Variable-latin.woff2"
        as="font" type="font/woff2" crossorigin>

  <!-- CSS inline oder extern -->
  <link rel="stylesheet" href="/css/fonts.css">
</head>

Font-Loading Checkliste

✅ WOFF2 als einziges Format verwenden
✅ Variable Fonts statt multiple statische Dateien
✅ font-display: swap für Body-Text
✅ font-display: optional für dekorative Fonts
✅ Maximal 1-2 Font-Familien pro Seite
✅ Kritischen Font mit <link rel="preload"> vorladen
✅ Font-Subsetting für nicht-benötigte Zeichensätze
✅ unicode-range für granulares Laden
✅ Metrisch angepasste Fallbacks für weniger Layout-Shift
✅ Self-Hosting für DSGVO-Konformität
✅ crossorigin-Attribut bei Preloads nicht vergessen
❌ Mehr als 3 Fonts laden
❌ Google Fonts CDN ohne Consent einbinden
❌ WOFF/TTF/EOT als primäres Format
❌ font-display: auto (browser-abhängig, unvorhersehbar)

Fazit

Web-Fonts haben sich stark entwickelt. Die wichtigsten Punkte:

  1. WOFF2 ist der Standard – andere Formate sind in 2024 unnötig
  2. Variable Fonts sparen Bandbreite und bieten unendliche Flexibilität
  3. font-display: swap für Body, optional für dekorative Fonts
  4. Self-Hosting ist Pflicht für DSGVO-Konformität in Deutschland
  5. Subsetting + unicode-range für optimale Performance
  6. Metrisch angepasste Fallbacks verhindern Layout-Shifts
  7. System Font Stacks wenn Custom Fonts nicht nötig sind – beste Performance bei null Bytes

Die goldene Regel: Weniger ist mehr. Jeder zusätzliche Font kostet Performance. Zwei gut gewählte Font-Familien (eine für Text, eine für Code) reichen für die meisten Projekte völlig aus.