Critical Rendering Path
Definition: Der Critical Rendering Path (kritischer Renderpfad) beschreibt die Abfolge von Schritten, die ein Browser vom Empfang des ersten HTML-Bytes bis zur visuellen Darstellung der ersten Pixel auf dem Bildschirm durchläuft: HTML-Parsing → DOM-Aufbau → CSS-Parsing → CSSOM-Aufbau → Render-Tree-Berechnung → Layout → Paint → Composite. Die Länge und Komplexität dieses Pfades bestimmt direkt die Zeit bis zum First Contentful Paint (FCP) und Largest Contentful Paint (LCP). Render-Blocking-Ressourcen (synchrones JavaScript und externe CSS-Dateien) unterbrechen den Pfad und verzögern die erste Darstellung.
Erläuterung
Der Browser kann keine Pixel malen bevor er einen Render Tree hat – und der Render Tree entsteht erst wenn DOM (aus HTML) und CSSOM (aus CSS) vollständig aufgebaut sind. Jede Ressource die diese beiden Schritte verzögert, verzögert alles danach. Das Verständnis des Critical Rendering Path ist die konzeptuelle Grundlage für alle Performance-Optimierungen rund um FCP und LCP.
Browser-Rendering-Schritte im Detail
- HTML-Parsing und DOM-Aufbau: Browser parst HTML-Bytes zu Tokens zu DOM-Nodes zu DOM-Tree; synchrones JavaScript stoppt HTML-Parsing komplett (Parser-Blocking); asynchrones Laden via defer oder async ermöglicht paralleles Parsen; DOM-Größe beeinflusst Geschwindigkeit (Ziel: <1.500 DOM-Nodes nach Lighthouse)
- CSS-Parsing und CSSOM-Aufbau: Externe CSS-Dateien sind render-blocking: Browser wartet auf vollständigen CSS-Download und -Parse bevor er Render Tree aufbaut; mehrere CSS-Dateien bedeuten mehrere blockierende Requests; @import in CSS erzeugt serielle Ladekettenprobleme
- Render Tree: Kombination aus DOM und CSSOM; enthält nur sichtbare Elemente (display:none ausgeschlossen); beschreibt visuelle Eigenschaften jedes Elements; Grundlage für Layout-Berechnung
- Layout (Reflow): Berechnung von Position und Größe jedes Elements basierend auf Viewport und Render Tree; teurer Prozess besonders bei vielen abhängigen Elementen; re-triggered durch DOM-Änderungen, Größenänderungen, Scroll (forced reflow)
- Paint und Composite: Paint: Pixels in Schichten (Layers) zeichnen; Composite: Schichten zusammenführen auf GPU; transform und opacity änderungen nur auf GPU (kein Layout/Paint re-trigger); CSS-Animationen mit transform bevorzugen
Render-Blocking-Ressourcen
- Synchrones JavaScript im <head>: Stoppt HTML-Parsing vollständig; Browser kann nicht weiterparsen bis Script geladen und ausgeführt; häufige Ursache für hohe FCP-Werte; Lösung: defer oder async Attribut; oder Script ans Ende des <body> verschieben
- Externe CSS-Dateien: <link rel="stylesheet"> im <head> ist render-blocking; Browser wartet auf CSS-Download bevor er Render Tree aufbaut; viele kleine CSS-Dateien addieren Blocking-Zeit; Lösung: CSS zusammenfassen und Critical CSS inline
- Render-Blocking messen: Lighthouse-Audit: «Eliminate render-blocking resources»; Chrome DevTools Network-Tab: pink markierte Requests sind render-blocking; WebPageTest: Waterfall-Diagramm zeigt Blocking-Zeiten visuell
Optimierungsmaßnahmen
- defer und async für Scripts: defer: Script lädt parallel, wird aber erst nach HTML-Parsing ausgeführt; behält Ausführungsreihenfolge; geeignet für die meisten Scripts; async: Script lädt und wird sofort ausgeführt sobald geladen (unterbricht kurz Parsing); geeignet für unabhängige Scripts wie Analytics
- Critical CSS inline: CSS für den sichtbaren Bereich (Above the Fold) direkt im <style>-Tag im HTML-Head inlinen; restliches CSS mit media="print" oder JavaScript asynchron nachladen; Tools: Critical (Node.js-Package), Penthouse, Critters (webpack/Vite Plugin)
- Resource Hints: <link rel="preload"> für kritische Ressourcen (LCP-Bild, kritische Fonts); <link rel="preconnect"> für Drittanbieter-Domains (Google Fonts, CDN); <link rel="dns-prefetch"> für DNS-Auflösung im Voraus; reduzieren Latenz für kritische Ressourcen
- Font-Loading optimieren: Systemfonts verwenden (kein Download nötig); font-display: swap verhindert FOIT (Flash of Invisible Text); Fonts preloaden: <link rel="preload" as="font" crossorigin>; nur benötigte Schriftgewichte laden