Core Web Vitals: Leitfaden zur Ressourcenpriorisierung

Steuere, welche Ressourcen zuerst laden und welche warten.

Arjen Karel Core Web Vitals Consultant
Arjen Karel - linkedin
Last update: 2026-02-25

Core Web Vitals Leitfaden zur Ressourcen-Priorisierung

Die standardmäßige Priorisierungs-Engine des Browsers arbeitet mit Heuristiken: unperfekte Schätzungen basierend auf Dateitypen und Position im Dokument. Ressourcen werden eingereiht, sobald der Preload-Scanner oder der DOM-Parser sie entdeckt.

Zuletzt überprüft von Arjen Karel im Februar 2026

priority waterfall web dev example

Das wird zum Problem. Netzwerkbandbreite und CPU sind keine unbegrenzten Ressourcen. Ein Beispiel: Jedes übertragene Byte für ein niedrig priorisiertes Tracking-Skript konkurriert beim gleichzeitigen Download direkt mit den Bytes für deinen Largest Contentful Paint (LCP).

Das ist nicht die Schuld des Browsers. Im HTML unseres Beispiels konnte der Browser nicht wissen, dass er die falschen Assets priorisiert hat. Das verzögerte das kritische Rendering.

Du weißt, was wichtig ist. Du steuerst diesen Zeitplan über zwei Mechanismen: Priorisierung (Verstärkung kritischer Signale) und De-Priorisierung (Verschiebung nicht-kritischer Ressourcen, bis sie weniger stören).

Grenzen der Browser-Heuristiken

Browser vergeben die Priorität basierend auf einem berechneten Prioritätswert („computed priority“). Dieser Wert leitet sich vom Asset-Typ (CSS, Skript, Bild) und seiner Position im HTML/DOM ab. Das System funktioniert meist gut für einfache Dokumente. Es versagt jedoch, wenn der Preload-Scanner Ressourcen nicht frühzeitig erkennt oder die falschen Ressourcen für einen frühen Download auslöst.

Standard-Prioritätsstufen in Chrome

Chrome nutzt fünf interne Prioritätsstufen: Highest, High, Medium, Low und Lowest. So weist er sie standardmäßig zu:

Ressource Standard-Priorität Mit fetchpriority="high" Mit fetchpriority="low"
CSS (im <head>) Highest (bereits Max.) High
Skript (blockierend, im <head>) Highest (bereits Max.) Low
Skript (async / defer) Low High Lowest
Font (via Preload) Highest (bereits Max.) n/a
Font (im CSS) High n/a n/a
Bild (Standard) Low High Lowest
Bild (erste 5 große) Medium High Low
Bild (im Viewport, nach Layout) High (bereits High) n/a

Das fetchpriority-Attribut wird für <img>-, <link>- und <script>-Elemente unterstützt. Es hat 93 % weltweite Browser-Unterstützung (Chrome 102+, Firefox 132+, Safari 17.2+, Edge 102+) und ist ein Progressive Enhancement: Browser ohne Unterstützung ignorieren es einfach. Laut dem Web Almanac 2025 nutzen aktuell 17 % der mobilen Seiten fetchpriority="high", aber nur 0,3 % verwenden fetchpriority="low". Das bedeutet: De-Priorisierung ist eine massiv ungenutzte Optimierung.

Die Grenzen des Preload-Scanners

Um die Erkennung zu beschleunigen, setzen Browser einen Preload-Scanner ein. Das ist ein leichtgewichtiger Parser, der dem Haupt-HTML-Parser vorausrennt, um Ressourcen-URLs zu finden. Dieser Scanner hat Einschränkungen (die ihn schnell und effektiv machen): Er parst nur HTML. Er kann nicht in CSS-Dateien sehen, führt kein JavaScript aus und rendert nicht (ergo erkennt er nicht, ob Ressourcen im Viewport sichtbar sind).

Die Folge: Jede Ressource, die in einem Stylesheet referenziert (wie ein Hintergrundbild oder ein Webfont), durch ein Skript eingefügt oder via Lazy Loading geladen wird, wird übersprungen. Sie wartet, bis der Haupt-Parser die gesamte Webseite herunterlädt und verarbeitet. Das erzeugt eine „Erkennungsverzögerung“. Der Browser weiß praktisch nicht, dass kritische Assets existieren.

Ressourcen-Konkurrenz

Wenn der Browser Assets entdeckt, versucht er oft, sie gleichzeitig mit anderen anstehenden Requests herunterzuladen. Konkurriert ein wichtiges LCP-Bild mit einem Skript mittlerer Priorität oder unwichtigen Bildern (wie Social-Media-Icons im Footer), teilen sie sich die verfügbare Bandbreite. Diese Konkurrenz verlängert die Ladezeit für beide. Das drückt den LCP-Wert in den Bereich „Needs Improvement“.

Manuelle Priorisierungs-Strategien

Für einen schnellen Rendering-Pfad musst du manuell eingreifen. Das Ziel: Maximiere die Bandbreite für den LCP und minimiere sie für alles andere. Bei den von CoreDash überwachten Seiten bestehen 82 % der Seiten, die fetchpriority="high" auf ihrem LCP-Bild nutzen, den LCP. Bei Seiten ohne dieses Attribut sind es nur 61 %.

1. Behebe die Erkennung mit Preloading

Du musst versteckte Assets manuell für den Preload-Scanner freilegen. Verschiebe kritische Ressourcen mit rel="preload" in den HTML-<head>. Das zwingt den Browser, sie sofort zu erkennen. Die Erkennungsverzögerung verschwindet. Für eine vollständige Anleitung siehe unseren Leitfaden zum Preloading des LCP-Bildes.

Die Implementierung:

<!-- Lege den Font sofort für den Scanner frei -->
<link rel="preload" as="font" type="font/woff2" href="/fonts/inter-bold.woff2" crossorigin>

<!-- Lege das LCP-Hintergrundbild sofort frei -->
<link rel="preload" as="image" href="/images/hero-banner.jpg" fetchpriority="high">

Für eine noch frühere Erkennung solltest du 103 Early Hints in Betracht ziehen. Das sendet Preload-Signale an den Browser, bevor die HTML-Antwort eintrifft.

2. Überschreibe LCP-Heuristiken

Browser weisen Bildern oft die Priorität „Low“ oder „Medium“ zu. Sie kennen die finalen Layout-Dimensionen beim ersten Abruf nicht. Der Browser kann erst nach dem Aufbau des Render-Trees feststellen, ob ein Bild der LCP ist. Das ist zu spät.

Die Implementierung:

Erzwinge den Status „High“ für das LCP-Element mit fetchpriority="high". Das umgeht interne Heuristiken und setzt das Bild an die Spitze der Download-Warteschlange. Google Flights verbesserte seinen LCP von 2,6 Sekunden auf 1,9 Sekunden (eine Verbesserung von 0,7 Sekunden) durch das Hinzufügen dieses einzigen Attributs.

<!-- Erzwinge sofortigen High-Priority-Fetch -->
<img src="hero.jpg" alt="Hero Product" fetchpriority="high">

Der schlimmste Fehler hierbei ist das Lazy Loading des LCP-Bildes. Das de-priorisiert aktiv das wichtigste Element auf der Seite.

3. De-priorisiere unwichtige Bilder

Das Freimachen von Bandbreite ist oft effektiver als die Erhöhung der Priorität. Du musst nicht-essentielle Assets explizit verzögern. Das räumt die Netzwerkleitung für kritische Ressourcen frei.

Die Implementierung:

  • Below the fold: Nutze loading="lazy", um Offscreen-Bilder zu verzögern, bis der Nutzer scrollt.
  • Above the fold, sekundär: Nutze fetchpriority="low" für Karussell-Slides oder sekundäre visuelle Elemente. Diese rendern anfänglich, sind aber weniger wichtig als der LCP.
  • Above the fold, visuell unwichtig: Umgehe den Preload-Scanner mit loading="lazy" und weise eine niedrige Bandbreiten-Priorität zu. Praktisch für kleine Bilder wie Flaggen oder Icons. Sie fallen beim ersten Rendern nie auf, können aber viele frühe Bandbreiten-Requests auslösen.
<!-- LCP-Bild: Höchste Priorität -->
<img src="slide-1.jpg" fetchpriority="high">

<!-- Sekundäres Karussell-Bild: Sofortiger Fetch, geringe Bandbreitennutzung -->
<img src="slide-2.jpg" fetchpriority="low">

<!-- Übersetzungs-Flaggen: Im Viewport, aber vor dem Preload-Scanner verstecken -->
<img src="dutch-flag.jpg" loading="lazy" fetchpriority="low">

<!-- Offscreen-Bild: Verzögerter Fetch -->
<img src="footer-promo.jpg" loading="lazy">

4. Kontrolliere die Skript-Ausführung

JavaScript blockiert den DOM-Parser. Bei Standard-<script>-Tags stoppt der Browser das HTML-Parsing. Er lädt die Datei herunter und führt sie aus. Unkontrollierte Skript-Ausführung schadet zudem direkt dem Interaction to Next Paint (INP). Sie blockiert den Main Thread.

Die Implementierung:

  • defer: Nutze dies für Applikations-Logik. Es lädt parallel herunter (Priorität Low) und führt das Skript erst nach dem vollständigen HTML-Parsing aus. Die Abhängigkeitsreihenfolge bleibt erhalten.
  • async: Nutze dies für unabhängige Third-Party-Skripte (wie Analytics). Es lädt parallel herunter und führt das Skript sofort nach Abschluss aus. Die Reihenfolge wird ignoriert.
  • async + fetchpriority="high": Nutze dies für kritische Async-Skripte (wie A/B-Testing). Sie brauchen einen schnellen Download, ohne das Parsing zu blockieren. Das hebt die Download-Priorität von Low auf High. Die Ausführung bleibt nicht-blockierend.
  • Inject: Umgeht den Preload-Scanner. Das Skript konkurriert nicht um frühe Bandbreite. Eingefügte Skripte werden als async behandelt.
  • Schedule + Inject: Füge Skripte zu einem späteren Zeitpunkt ein, zum Beispiel wenn das Load-Event feuert.
<!-- Applikations-Logik: Nicht-blockierend, erhält Ausführungsreihenfolge -->
<script src="app.js" defer></script>

<!-- Third-Party-Consent: Nicht-blockierend, unabhängige Ausführung -->
<script src="consent.js" async></script>

<!-- Kritisches Async: Schneller Download, nicht-blockierende Ausführung -->
<script src="ab-test.js" async fetchpriority="high"></script>

<script>
  /* Beispiel: Analytics injizieren */
  const script = document.createElement('script');
  script.src = 'analytics.js';
  script.async = true;
  document.head.appendChild(script);

  /* Beispiel: Chat injizieren + einplanen */
  window.addEventListener('load', () => {
    const chatScript = document.createElement('script');
    chatScript.src = 'chat-widget.js';
    document.head.appendChild(chatScript);
  });
</script>

Eine umfassende Übersicht aller verfügbaren Techniken findest du unter 16 Methoden, um JavaScript zu verzögern und async vs. defer JavaScript. Eine Anleitung zur Kategorisierung von Skripten nach Kritikalität gibt es unter JavaScript-Prioritätsstufen.

5. Entblocke das CSS-Rendering

CSS ist von Natur aus render blocking. Der Browser weiß nicht, wie die Seite ohne CSS aussieht. Also lädt und parst er zuerst die Stylesheets.

Optimierungs-Strategien:

  • Vermeide @import: Es erzeugt sequenzielle Abhängigkeitsketten. Das ruiniert die Performance.
  • Optimiere die Bundle-Größe: Vermeide CSS-Dateien unter 3 kB (Overhead) und über 20 kB (blockierend). Ziele idealerweise auf ~15-kB-Dateien ab.
  • Async Loading: Lade Offscreen-Styles asynchron. Das entblockt den kritischen Pfad.
  • Critical-CSS-Kompromiss: Das Inlinen von Critical CSS verbessert den ersten Seitenaufruf. Es umgeht jedoch den Browser-Cache. Das kann nachfolgende Seitenaufrufe verzögern.

Die Implementierung:

Eliminiere @import komplett. Nutze <link>-Tags für paralleles Laden. Nutze bei nicht-kritischem CSS (wie Print-Styles) das media-Attribut. Das entblockt den Main Thread. Mehr zur CSS-Optimierung findest du unter Ungenutztes CSS entfernen.

<!-- Critical CSS: Blockiert Rendering (Korrekt) -->
<link rel="stylesheet" href="main.css">

<!-- Print-CSS: Nicht-blockierend, bis das Print-Event eintritt -->
<link rel="stylesheet" href="print.css" media="print">

<!-- Async-Pattern: Lädt mit Priorität Low, wird bei Load angewendet -->
<link rel="stylesheet" href="non-critical.css" media="print" onload="this.media='all'">

6. Stabilisiere das Font-Rendering

Fonts sind schwere, blockierende Ressourcen. Eine effektive Priorisierung erfordert strikte Limits für Downloads. Du brauchst Kontrolle über das Rendering.

Optimierungs-Strategien:

  • Strikte Preload-Limits: Preloade nur die 1 bis 2 wichtigsten Font-Dateien (meist LCP-Text). Das Preloading von über 5 Fonts verstopft die Bandbreite.
  • Self-Hosting: Hoste deine Webfonts selbst, anstatt sie von einem Third-Party-CDN zu laden. Das eliminiert den zusätzlichen Verbindungsaufbau.
  • Reduziere die Payload: Nutze Variable Fonts (eine Datei für alle Strichstärken) und Subsetting (Entfernung ungenutzter Zeichen). Das minimiert die Dateigröße.
  • Rendering-Strategie:

Die Implementierung:

<!-- Preloade NUR das kritische Subset (z. B. Header + Body) -->
<link rel="preload" href="/fonts/inter-var.woff2" as="font" type="font/woff2" crossorigin>

<style>
  @font-face {
    font-family: 'Inter Variable';
    src: url('/fonts/inter-var.woff2') format('woff2-variations');
    /* Wähle basierend auf Stabilitäts-Anforderungen: */
    font-display: optional; /* Kein Layout Shift, aber Font bleibt eventuell Fallback */
    /* font-display: swap;     Schnellste Text-Sichtbarkeit, riskiert aber Layout Shift */
  }
</style>

7. Beschleunige Verbindungen

Bevor ein Browser eine Ressource von einer Third-Party-Origin herunterladen kann, muss er einen DNS-Lookup durchführen, eine TCP-Verbindung aufbauen und die TLS-Verschlüsselung aushandeln. Das kostet Zeit. Du kannst diese Verzögerung eliminieren. Sage dem Browser, dass er Verbindungen frühzeitig aufbauen soll.

Die Implementierung:

  • preconnect: Nutze dies für kritische Third-Party-Origins, die der Browser sicher benötigt. Es führt den vollständigen Handshake (DNS + TCP + TLS) vorab durch.
  • dns-prefetch: Nutze dies für weniger kritische Origins. Es führt nur die DNS-Auflösung durch. Das ist ressourcenschonender, spart aber dennoch 20 bis 120 ms.
<!-- Kritische Third-Party: Vollständige frühe Verbindung -->
<link rel="preconnect" href="https://cdn.example.com">

<!-- Fallback für ältere Browser -->
<link rel="dns-prefetch" href="https://cdn.example.com">

Limitiere Preconnect auf 2 bis 4 Origins. Jede Verbindung verbraucht CPU und Bandbreite. Zu viele Preconnects konkurrieren mit tatsächlichen Ressourcen-Downloads. Das kann der Performance schaden, anstatt zu helfen. Laut dem Web Almanac 2025 nutzen 22 % der Seiten Preconnect und 24 % nutzen dns-prefetch. Platziere beides so früh wie möglich im <head>, noch vor jeglichen blockierenden Ressourcen.

About the author

Arjen Karel is a web performance consultant and the creator of CoreDash, a Real User Monitoring platform that tracks Core Web Vitals data across hundreds of sites. He also built the Core Web Vitals Visualizer Chrome extension. He has helped clients achieve passing Core Web Vitals scores on over 925,000 mobile URLs.

Dein Lighthouse-Score zeigt nicht das ganze Bild.

Deine Besucher sitzen auf Android-Geräten im 4G-Netz. Ich analysiere, was die tatsächlich sehen.

RUM-Daten auswerten
Core Web Vitals: Leitfaden zur Ressourcenpriorisierung Core Web Vitals Core Web Vitals: Leitfaden zur Ressourcenpriorisierung