INP Presentation Delay: DOM-Größe, Layout-Arbeit und Rendering-Optimierung
Lerne, wie du INP-Probleme findest und behebst, die durch Präsentationsverzögerungen verursacht werden.
Interaction to Next Paint (INP)-Probleme durch Darstellungsverzögerung
Diese Seite ist Teil unserer Serie zum Interaction to Next Paint (INP). Der INP misst die Gesamtzeit von einer Nutzerinteraktion bis zur nächsten visuellen Aktualisierung. Die Darstellungsverzögerung ist die dritte und letzte Phase des INP. Sie folgt auf die Eingabeverzögerung und die Verarbeitungszeit. Wenn der INP neu für dich ist, lies zuerst unseren Leitfaden zur Erkennung und Behebung von INP-Problemen.
Kurz gesagt: Der Interaction to Next Paint (INP) misst, wie lange es dauert, bis ein Nutzer nach einer Interaktion eine visuelle Änderung auf einer Seite sieht. Dieser INP lässt sich in 3 Komponenten unterteilen: „Eingabeverzögerung“, „Verarbeitungszeit“ und „Darstellungsverzögerung“.
Die Darstellungsverzögerung trägt am meisten zum gesamten INP bei. Sie macht im Durchschnitt etwa 42 % der gesamten INP-Zeit aus. Die Optimierung deiner Rendering-Pipeline und die Vereinfachung deiner HTML-Struktur sind der größte Hebel zur Verbesserung des INP.
Darstellungsverzögerung: Hast du schon mal auf einen Button geklickt und dich gewundert, warum das Ergebnis einen Bruchteil einer Sekunde zu spät erschien? Das ist der Interaction to Next Paint (INP) in Aktion. Die Darstellungsverzögerung ist der letzte Schritt im Interaktionsprozess. Sie beginnt, nachdem dein Klick verarbeitet wurde, aber bevor du visuelle Änderungen siehst.
Table of Contents!
- Interaction to Next Paint (INP)-Probleme durch Darstellungsverzögerung
- Darstellungsverzögerung verstehen
- Darstellungsverzögerung und der INP
- Was verursacht eine hohe Darstellungsverzögerung?
- Darstellungsverzögerung reduzieren
- Lange Darstellungsverzögerungen erkennen
- Darstellungsverzögerung mit RUM-Daten erkennen
- Darstellungsverzögerung mit Long Animation Frames (LoAF) messen
- Erkunde die anderen INP-Phasen
Darstellungsverzögerung verstehen
Die Darstellung ist die letzte Phase einer Interaktion. Die Darstellungsverzögerung ist die Zeit, die der Browser braucht, um visuelle Aktualisierungen nach der Interaktion zu rendern. Sie beginnt, wenn die Event-Handler der Interaktion abgeschlossen sind. Sie endet, wenn der nächste Frame (mit den visuellen Änderungen) gezeichnet wird. Verschiedene Faktoren beeinflussen die Darstellungsverzögerung. Dazu gehören die Komplexität des Layouts, die Größe des DOMs und der erforderliche Rendering-Aufwand.

Der Interaction to Next Paint (INP) lässt sich in 3 Teilbereiche unterteilen: „Eingabeverzögerung“, „Verarbeitungszeit“ und „Darstellungsverzögerung“.
Darstellungsverzögerung und der INP
Die Darstellungsverzögerung ist die letzte Phase des INP. Im Durchschnitt macht sie etwa 42 % der gesamten INP-Zeit aus. Damit ist sie die Hauptursache für langsame Interaktionen.

Bei CoreDash sammeln wir stündlich Millionen von Core Web Vitals-Datenpunkten. Basierend auf diesen Daten macht die Darstellungsverzögerung 42 % des Interaction to Next Paint aus. Das ist mehr als die Verarbeitungszeit (40 %) und deutlich mehr als die Eingabeverzögerung (18 %). Obwohl sie den größten Anteil hat, ist die Darstellungsverzögerung oft die am schwersten zu optimierende Phase. Sie betrifft die Rendering-Pipeline des Browsers und nicht deinen Anwendungscode.
Beispiel für Darstellungsverzögerung: Stell dir vor, du suchst auf deinem Smartphone in einem Online-Shop nach neuen Schuhen. Du tippst auf ein Produktbild, um mehr Details zu sehen. Dein Smartphone ist jedoch etwas älter und hat Mühe, mitzuhalten. Du tippst auf das Bild (Interaktion). Das Smartphone braucht etwas Zeit, um die Anfrage zu verarbeiten und die Anzeige zu aktualisieren (Verarbeitungszeit). Die Website muss die neue Seite mit dem größeren Bild und den Details rendern. Schließlich dauert es merklich lange, bis die neuen Produktdetails und das Bild auf deinem Bildschirm erscheinen (Darstellungsverzögerung). Diese Verzögerung im INP frustriert Nutzer. Deshalb ist es wichtig, sie zu beheben.
Was verursacht eine hohe Darstellungsverzögerung?
Die Darstellungsverzögerung umfasst die gesamte Arbeit des Browsers nach dem Ende deiner Event-Handler und bevor Pixel auf dem Bildschirm erscheinen. Dazu gehören die Neuberechnung von Stilen, die Layoutberechnung, das Zeichnen und das Compositing. Mehrere Faktoren tragen zu einer hohen Darstellungsverzögerung bei:
Große DOM-Größe
Ein großes oder tief verschachteltes DOM ist eine der häufigsten Ursachen für eine hohe Darstellungsverzögerung. Jedes Mal, wenn der Browser den visuellen Zustand der Seite nach einer Interaktion aktualisiert, muss er Stile neu berechnen, das Layout bestimmen und betroffene Elemente neu zeichnen. Die Kosten für jeden dieser Schritte steigen mit der Anzahl der betroffenen DOM-Knoten.
Google empfiehlt, das DOM unter 1.400 Elementen zu halten. Die maximale Tiefe sollte 32 Ebenen betragen. Ein übergeordneter Knoten sollte nicht mehr als 60 untergeordnete Elemente haben (siehe den Lighthouse DOM Size Audit). Wenn dein DOM diese Grenzwerte überschreitet, verbringt der Browser nach jeder Interaktion viel mehr Zeit mit der Stil- und Layoutberechnung.
Stell dir dieses Szenario vor: Ein Nutzer klickt auf einen Button, der eine CSS-Klasse an einem Container-Element umschaltet. Wenn dieser Container 5.000 untergeordnete Knoten hat, muss der Browser möglicherweise die Stile für alle neu berechnen. Auch dann, wenn sich nur wenige Elemente optisch verändern. Diese Stilneuberechnung erfolgt synchron vor dem nächsten Paint. Das erhöht die Darstellungsverzögerung direkt.
Spezifische Techniken zur Reduzierung deines DOMs findest du in unserem Leitfaden zur Behebung einer übermäßigen DOM-Größe.
Übermäßige Layout-Arbeit
Layout (auch „Reflow“ genannt) ist der Prozess, bei dem der Browser die Position und die Abmessungen jedes sichtbaren Elements auf der Seite berechnet. Nach einer Interaktion, die das DOM verändert oder CSS-Eigenschaften beeinflusst, die die Geometrie verändern (width, height, margin, padding, top, left), muss der Browser das Layout berechnen. Erst danach kann er den aktualisierten Frame zeichnen.
Zwei Muster sind besonders schädlich für die Darstellungsverzögerung:
Ein Forced Synchronous Layout tritt auf, wenn JavaScript eine Layout-Eigenschaft (wie offsetHeight oder getBoundingClientRect()) liest, nachdem eine DOM-Änderung das Layout ungültig gemacht hat. Der Browser ist gezwungen, das Layout synchron innerhalb deines Event-Handlers durchzuführen, um einen genauen Wert zurückzugeben. Diese Layout-Arbeit wird dann Teil der Verarbeitungszeit. Jedes nachfolgende Layout, das durch weitere DOM-Änderungen ausgelöst wird, wird Teil der Darstellungsverzögerung.
Layout Thrashing ist das wiederholte Muster, in einer Schleife in das DOM zu schreiben und dann Layout-Eigenschaften zu lesen. Jeder Lesevorgang zwingt den Browser, das Layout neu zu berechnen. Jeder Schreibvorgang macht das Layout wieder ungültig. Dies kann Dutzende oder Hunderte von unnötigen Layoutberechnungen pro Interaktion verursachen. Hier ist ein Beispiel für Layout Thrashing und wie du es behebst:
// SCHLECHT: Layout Thrashing innerhalb einer Schleife
function resizeItems() {
const items = document.querySelectorAll('.item');
items.forEach(item => {
// Lesen (erzwingt Layout)
const parentWidth = item.parentElement.offsetWidth;
// Schreiben (macht Layout ungültig)
item.style.width = parentWidth + 'px';
});
}
// GUT: Erst alle lesen, dann alle schreiben
function resizeItems() {
const items = document.querySelectorAll('.item');
// Zuerst alle Werte lesen
const widths = Array.from(items).map(
item => item.parentElement.offsetWidth
);
// Dann alle Werte schreiben
items.forEach((item, i) => {
item.style.width = widths[i] + 'px';
});
} Clientseitiges Rendering in Single Page Applications
Clientseitiges Rendering von HTML kann die Darstellungsverzögerung erheblich beeinflussen. Das gilt besonders in Single Page Applications (SPAs). Wenn eine Nutzerinteraktion einen Routenwechsel oder ein großes UI-Update auslöst, muss das SPA-Framework Folgendes tun:
- Den Virtual-DOM-Diffing-Algorithmus ausführen, um Änderungen zu ermitteln
- Die resultierenden DOM-Mutationen auf das echte DOM anwenden
- Die Stilneuberechnung und das Layout für alle betroffenen Elemente auslösen
- Den aktualisierten Frame zeichnen
In React-Anwendungen ist der Virtual-DOM-Reconciliation-Prozess Teil der Verarbeitungszeit. Die resultierenden DOM-Mutationen und ihre Rendering-Kosten fallen jedoch in die Darstellungsverzögerung. Je mehr DOM-Knoten dein Komponentenbaum erzeugt, desto teurer sind die Reconciliation und die anschließende Rendering-Arbeit.
So milderst du das in React- und Next.js-Anwendungen ab:
- Nutze
React.memo(), um unnötige Re-Renders von untergeordneten Komponenten zu verhindern, die dieselben Props erhalten. - Nutze
useDeferredValue()für Werte, die teure Re-Renders auslösen. So kann React dringendere Updates priorisieren. - Halte Komponentenstrukturen flach. Tief verschachtelte Komponentenhierarchien erzeugen ein tief verschachteltes DOM. Das erhöht die Kosten für die Reconciliation und das Browser-Rendering.
- Nutze Virtualisierungsbibliotheken (wie
react-windowoder@tanstack/react-virtual) für lange Listen. So enthält das DOM nur die sichtbaren Elemente.
Darstellungsverzögerung reduzieren
DOM-Größe minimieren
Der größte Gewinn für die Darstellungsverzögerung ist ein kleines DOM:
- Entferne ungenutzte HTML-Elemente, insbesondere tief verschachtelte Wrapper-Divs.
- Nutze Listenvirtualisierung für lange Listen (rendere nur sichtbare Elemente plus einen kleinen Puffer).
- Verflache tief verschachtelte Strukturen, wo immer das möglich ist.
- Nutze CSS Grid und Flexbox anstelle von verschachtelten Divs für das Layout.
// Lange Listen virtualisieren, um die DOM-Größe zu reduzieren
// Vorher: 10.000 Elemente im DOM
<ul>
{allItems.map(item =>
<li key="{item.id}">{item.name}</li>)
}
</ul>
// Nachher: Nur sichtbare Elemente im DOM (mit react-window)
import { FixedSizeList } from 'react-window';
<fixedsizelist height="{600}"
itemcount="{allItems.length}"
itemsize="{50}" width="100%">
{({ index, style }) => (
<div style="{style}">{allItems[index].name}</div>
)}
</fixedsizelist>
content-visibility nutzen, um unsichtbare Inhalte verzögert zu rendern
Die CSS-Eigenschaft content-visibility weist den Browser an, das Rendering von unsichtbaren Inhalten zu überspringen, bis der Nutzer in deren Nähe scrollt. Das reduziert die Rendering-Arbeit während Interaktionen. Der Umfang der Stilneuberechnung und des Layouts wird auf den sichtbaren Teil der Seite beschränkt.
/* Wende content-visibility auf Bereiche Below-the-Fold an */
.below-fold-section {
content-visibility: auto;
contain-intrinsic-size: auto 500px;
}
/* Wende es auf einzelne Elemente in langen Listen an */
.list-item {
content-visibility: auto;
contain-intrinsic-size: auto 80px;
} Die Eigenschaft contain-intrinsic-size liefert eine geschätzte Höhe. So kann der Browser die Größe der Scrollbar korrekt berechnen, ohne den Inhalt zu rendern. Das verhindert Layout Shifts, wenn der Nutzer scrollt und der Inhalt sichtbar wird.
Weitere CSS-Optimierungsstrategien zur Reduzierung der Rendering-Kosten findest du in unserem Leitfaden zum Entfernen von ungenutztem CSS.
Durch Interaktionen ausgelöste Layout-Arbeit minimieren
Bevorzuge beim Design von Interaktionen CSS-Eigenschaften, die kein Layout auslösen. Eigenschaften wie transform und opacity können vom GPU-Compositor verarbeitet werden, ohne Layout oder Paint auszulösen. Anstatt top, left, width oder height zu animieren, nutze transform: translate() und transform: scale(). Die vollständige Liste der CSS-Eigenschaften, die Layout auslösen, findest du im web.dev Rendering Performance Guide.
Nutze die CSS-Eigenschaft will-change. Damit gibst du dem Browser den Hinweis, dass ein Element animiert wird. Das erlaubt dem Browser, eine separate Compositor-Ebene für das Element zu erstellen. Dadurch wird das Rendering vom Rest der Seite isoliert:
/* Hebe Elemente auf ihre eigene Compositor-Ebene */
.animated-element {
will-change: transform, opacity;
}
/* Schalte die Sichtbarkeit mit opacity statt display um */
.modal {
opacity: 0;
pointer-events: none;
transform: translateY(10px);
transition: opacity 0.2s, transform 0.2s;
}
.modal.active {
opacity: 1;
pointer-events: auto;
transform: translateY(0);
} Lange Darstellungsverzögerungen erkennen
Um lange Darstellungsverzögerungen zu erkennen, kannst du den Performance Profiler von Chrome nutzen. Öffne die DevTools (Strg+Shift+I), navigiere zum Tab Performance, klicke auf Record und interagiere mit der Seite.
Du kannst dann die Timeline einer Interaktion analysieren und die verschiedenen Phasen visualisieren, einschließlich der Darstellungsverzögerung. Untersuche die Rendering-Updates, die nach Abschluss der Event-Handler auftreten. So kannst du Engpässe identifizieren, die zu einer langen Darstellungsverzögerung beitragen. Suche nach großen Einträgen für „Recalculate Style“, „Layout“ und „Paint“ in der Timeline. Diese repräsentieren die Arbeit, die der Browser während der Darstellungsverzögerung leistet.

Darstellungsverzögerung mit RUM-Daten erkennen
Darstellungsverzögerung mit Long Animation Frames (LoAF) messen
Die Long Animation Frames (LoAF) API zeigt genau, was Rendering-Verzögerungen bei Nutzerinteraktionen verursacht. Die API liefert dir Timing-Daten. Damit trennst du die Verarbeitungszeit von der Darstellungsverzögerung. So findest du genau heraus, welche Skripte das Rendering verlangsamen.
Die wichtigsten LoAF-Eigenschaften zum Verständnis der Darstellungsverzögerung sind:
renderStart: Wann der Browser mit der Rendering-Phase begann (Stilneuberechnung, Layout, Paint)styleAndLayoutStart: Wann die Stil- und Layoutberechnung begannduration: Gesamtdauer des langen Animation FramesblockingDuration: Wie viel des Frames durch Skripte blockiert wurde
LoAF ist derzeit nur für Chromium verfügbar (Chrome 123+). Bei anderen Browsern nutzt du die Traces des Chrome DevTools Performance-Panels zur Analyse der Rendering-Arbeit.
Die Differenz zwischen dem Ende der Skriptausführung und dem Ende des Frames stellt die reinen Rendering-Kosten dar. Das ist die Darstellungsverzögerung. So beobachtest und protokollierst du diese Daten:
// Darstellungsverzögerung mit der LoAF API messen
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (entry.duration > 50) {
const scriptEnd = Math.max(
...entry.scripts.map(s => s.startTime + s.duration)
);
const presentationDelay = (
entry.startTime + entry.duration
) - Math.max(scriptEnd, entry.renderStart);
console.log('Presentation delay breakdown:', {
totalDuration: entry.duration,
renderStart: entry.renderStart,
styleAndLayoutStart: entry.styleAndLayoutStart,
estimatedPresentationDelay: presentationDelay,
scriptCount: entry.scripts.length
});
}
}
});
observer.observe({
type: 'long-animation-frame',
buffered: true
}); RUM-Tools wie CoreDash integrieren LoAF-Daten. Sie zeigen dir mit vollständiger Skriptzuordnung, welche Skripte und DOM-Änderungen Rendering-Verzögerungen verursachen.
Erkunde die anderen INP-Phasen
Um deinen INP in den Griff zu bekommen, kümmere dich auch um die anderen beiden Phasen:
- Eingabeverzögerung: Minimiere die Wartezeit vor der Ausführung von Event-Handlern. Die Eingabeverzögerung ist meistens die kürzeste Phase. Sie steigt jedoch beim Seitenstart stark an, wenn der Main Thread ausgelastet ist.
- Verarbeitungszeit: Optimiere den Event-Handler-Code, der während der Interaktion läuft. Auf den meisten Seiten zahlt sich hier der Großteil deiner Optimierungsarbeit aus.
Einen vollständigen Diagnose-Workflow findest du in unserem Leitfaden zum Finden und Beheben von INP-Problemen. Weitere Strategien zur Rendering-Optimierung findest du in unseren Leitfäden zur Behebung einer übermäßigen DOM-Größe und zum Entfernen von ungenutztem CSS. Kehre zur INP-Übersichtsseite zurück, um den vollständigen Überblick zu erhalten.
CoreDash spricht MCP.
Häng es an Claude oder einen beliebigen AI Agent und frag: Warum ist mein INP letzten Dienstag hochgegangen?
So funktioniert's