Core Web Vitals optimieren: Web-Performance Guide
Vor ein paar Wochen war ich in den PageSpeed-Logs einer Seite, die ich technisch für sauber hielt: SSR, Image-Optimization, alles ordentlich. Trotzdem 38/100 bei Mobile-Performance, INP rot, LCP gerade so im gelben Bereich. Lehre: Core Web Vitals messen Realität, nicht Konfiguration.
Die drei Metriken sind seit 2024 stabil — INP hat FID ersetzt, sonst keine großen Änderungen. Was sich geändert hat, ist der Mess-Mechanismus: CrUX (Chrome User Experience Report) liefert echte Daten echter Nutzer, nicht synthetische Lab-Werte. Das macht Optimierung manchmal frustrierend, weil Lab-Tests grün sind und Field-Daten trotzdem rot.
Was die drei Metriken eigentlich messen
LCP (Largest Contentful Paint) — wann ist das größte sichtbare Element gerendert. Meist ein Hero-Bild oder ein großer Headline-Block. Threshold: ≤ 2.5 s.
INP (Interaction to Next Paint) — wie lange braucht der Browser, um auf eine Nutzerinteraktion mit visuellem Feedback zu reagieren. Misst alle Interaktionen, nicht nur die erste. Threshold: ≤ 200 ms.
CLS (Cumulative Layout Shift) — wie stark verschiebt sich der sichtbare Content während des Ladens. Threshold: ≤ 0.1.
Was die drei verbindet: alle field-gemessen, also abhängig von Endgerät und Verbindung des echten Nutzers.
LCP optimieren
Hauptursachen für schlechtes LCP, in absteigender Häufigkeit:
- Bilder, die nicht priorisiert geladen werden
- Render-blocking JS oder CSS
- Server-TTFB zu hoch
- Web-Fonts, die FOIT/FOUT verursachen
Konkret: das LCP-Element identifizieren (PerformanceObserver oder PageSpeed Insights), dann in Reihenfolge prüfen:
- Hat das Bild
loading="eager"undfetchpriority="high"? - Wird ein
<link rel="preload">für kritische Assets gesetzt? - Ist die Komprimierung sinnvoll? AVIF oder WebP statt JPEG bei richtigen Dimensionen?
Bei meinem Portfolio hatte ich ein 200 KB Hero-Bild als WebP mit loading="lazy" (Default in Next.js bei <Image>). LCP lag bei 3.2 s. Mit priority (was eager + fetchpriority="high" setzt) ging's auf 1.4 s. Eine Zeile Code.
INP ist das neue Performance-Problem
Bis Ende 2024 war FID die Interaktions-Metrik. FID war einfach: misst die Verzögerung zwischen Klick und Beginn der Verarbeitung. INP misst Klick bis fertig gerendertes Update — also den vollen Roundtrip.
Folge: Apps mit teurem Rendering (große React-Komponenten-Trees, schwere State-Updates) sehen plötzlich schlecht aus, obwohl Lab-Tests das nicht zeigten.
Optimierungs-Hebel:
- Heavy Updates batchen (
startTransitionin React) - Lange Tasks aufteilen (
scheduler.yield()in modernen Browsern) - Re-Renders reduzieren — Memoization gezielt, nicht überall
- Synchrone JS-Arbeit aus Event-Handlern verbannen
Bei mir hat am meisten geholfen: die Suche verzögert (useDeferredValue) und die Filterlogik in einen Web Worker ausgelagert. INP von 280 ms auf 95 ms.
CLS — Reservierung ist alles
CLS-Probleme entstehen fast immer dadurch, dass Elemente in den DOM rein-poppen und vorhandenen Content verdrängen. Bilder ohne width/height, Webfonts, die nach dem ersten Render nochmal alles neu layouten, dynamische Banner.
Das beste Mittel: Platz reservieren, bevor der Inhalt da ist.
<img src="hero.webp" width="1200" height="600" alt="...">
Das Browser-Layout reserviert anhand des Aspekt-Ratios den Platz. Bei Webfonts: font-display: swap plus passendes Fallback mit size-adjust, damit das Layout beim Font-Wechsel nicht springt.
@font-face {
font-family: 'Inter';
src: url('/fonts/inter.woff2') format('woff2');
font-display: swap;
size-adjust: 95%;
}
Brotli und Caching helfen, aber nicht so viel wie man denkt
Es ist verlockend, Performance-Probleme über Komprimierung lösen zu wollen. Brotli statt Gzip, lange Cache-Header, alles richtig — und LCP geht trotzdem nicht runter, weil das Hero-Bild beim ersten Aufruf nicht im Cache ist.
Der erste Besuch (cold cache) ist die Realität für viele Nutzer. Optimierung muss dort ansetzen, nicht beim warm-cache-Request, der ohnehin schnell ist.
Was ich heute anders mache
Weniger JS shippen, mehr SSR. Weniger CSS-in-JS, mehr static CSS. Bilder explizit dimensionieren, immer. Und vor allem: Field-Daten anschauen, nicht Lab-Tests. PageSpeed Insights zeigt sowohl als auch — der Unterschied zwischen den beiden ist oft das eigentliche Problem.