INP-Presentation-Delay: DOM-Größe, Layout-Arbeit und Rendering-Optimierung

So erkennst und behebst du INP-Probleme durch Presentation Delay

Arjen Karel
Aktualisiert am · 9 Min. Lesezeit
Teilen

Interaction to Next Paint (INP): Probleme durch Presentation Delay

Diese Seite ist Teil unserer Artikelreihe zum Interaction to Next Paint (INP). Der INP misst die gesamte Zeitspanne von einer Nutzerinteraktion bis zum nächsten visuellen Update. Der Presentation Delay ist die dritte und letzte Phase des INP – nach dem Input Delay und der Processing Time. Wenn du neu beim INP bist, lies zuerst unseren Leitfaden: INP-Probleme erkennen und beheben.

Kurz gesagt: Der Interaction to Next Paint (INP) misst, wie lange es dauert, bis Nutzer nach einer Interaktion eine visuelle Änderung auf der Seite sehen. Der INP setzt sich aus 3 Komponenten zusammen: „Input Delay“, „Processing Time“ und „Presentation Delay“.

Der Presentation Delay ist der Hauptverursacher beim gesamten INP und macht im Schnitt rund 42 % der gesamten INP-Zeit aus. Deine Rendering-Pipeline zu optimieren und deine HTML-Struktur zu vereinfachen, ist der größte Hebel, um den INP zu verbessern.

Presentation Delay: Schon mal auf einen Button geklickt und dich gewundert, warum das Ergebnis einen Sekundenbruchteil zu spät sichtbar war? Genau das ist der Interaction to Next Paint (INP) in der Praxis. Der Presentation Delay ist der letzte Schritt im Interaktionsprozess: Er setzt ein, nachdem dein Klick verarbeitet wurde, aber bevor du visuelle Änderungen siehst.

Presentation Delay verstehen

Die Präsentation ist die letzte Phase einer Interaktion. Der Presentation Delay beschreibt die Zeit, die der Browser braucht, um visuelle Updates nach der Interaktion zu rendern. Der Presentation Delay beginnt, sobald die Event-Handler für die Interaktion fertig ausgeführt sind, und endet, wenn der nächste Frame (mit den visuellen Änderungen) gezeichnet wird. Verschiedene Faktoren beeinflussen den Presentation Delay: wie komplex das Layout ist, wie groß das DOM ist und wie viel Rendering-Arbeit anfällt.

INP breakdown diagram showing green Input Delay, purple Processing Time, and blue Presentation Delay stages

Der Interaction to Next Paint (INP) lässt sich in 3 Teilbereiche unterteilen: „Input Delay“, „Processing Time“ und „Presentation Delay“.

Presentation Delay und der INP

Der Presentation Delay ist die letzte Phase des INP. Im Schnitt macht er rund 42 % der gesamten INP-Zeit aus und ist damit der größte Einzelfaktor für langsame Interaktionen.

CoreDash pie chart showing Input Delay at 18% of INP, Processing Time 40%, Presentation Delay 42%

Bei CoreDash erfassen wir stündlich Millionen von Core-Web-Vitals-Datenpunkten. Basierend auf diesen Daten macht der Presentation Delay 42 % des Interaction to Next Paint aus. Das ist mehr als die Processing Time (40 %) und deutlich mehr als der Input Delay (18 %). Obwohl er den größten Anteil ausmacht, ist der Presentation Delay oft am schwersten zu optimieren – denn er betrifft die Rendering-Pipeline des Browsers und nicht deinen eigenen Anwendungscode.

Beispiel für Presentation Delay: 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 allerdings schon etwas älter und kommt kaum hinterher. Du tippst auf das Bild (Interaktion). Das Smartphone braucht etwas Zeit, um die Anfrage zu verarbeiten und die Anzeige zu aktualisieren (Processing Time). Die Website muss die neue Seite mit dem größeren Bild und den Details rendern. Schließlich dauert es spürbar lange, bis die neuen Produktdetails und das Bild auf deinem Bildschirm erscheinen (Presentation Delay). Diese Verzögerung beim INP frustriert Nutzer – genau deshalb ist es wichtig, sie zu beheben.

Was verursacht einen hohen Presentation Delay?

Der Presentation Delay umfasst die gesamte Arbeit, die der Browser erledigt, nachdem deine Event-Handler fertig sind und bevor Pixel auf dem Bildschirm erscheinen. Dazu gehören Style-Neuberechnungen, Layout-Berechnungen, Paint und Compositing. Mehrere Faktoren führen zu einem hohen Presentation Delay:

Große DOM-Größe

Ein großes oder tief verschachteltes DOM ist eine der häufigsten Ursachen für einen hohen Presentation Delay. Jedes Mal, wenn der Browser den visuellen Zustand der Seite nach einer Interaktion aktualisiert, muss er Styles neu berechnen, das Layout kalkulieren und die betroffenen Elemente neu zeichnen. Der Aufwand für jeden dieser Schritte skaliert mit der Anzahl der betroffenen DOM-Knoten.

Google empfiehlt, das DOM unter 1.400 Elementen zu halten – mit einer maximalen Tiefe von 32 Ebenen und höchstens 60 Kindelementen pro Elternknoten (siehe das Lighthouse-DOM-Size-Audit). Überschreitet dein DOM diese Schwellenwerte, braucht der Browser nach jeder Interaktion deutlich mehr Zeit für Style-Neuberechnungen und Layout-Berechnungen.

Ein typisches Szenario: Ein Nutzer klickt auf einen Button, der eine CSS-Klasse an einem Container-Element umschaltet. Hat dieser Container 5.000 Nachfahrenelemente, muss der Browser potenziell für alle die Styles neu berechnen – selbst wenn sich optisch nur ein Bruchteil davon ändert. Diese Style-Neuberechnung läuft synchron vor dem nächsten Paint und treibt den Presentation Delay direkt nach oben.

Konkrete Techniken, um dein DOM zu verkleinern, findest du in unserem Leitfaden: Zu große DOM-Größe beheben.

Übermäßige Layout-Arbeit

Beim Layout (auch „Reflow“ genannt) berechnet der Browser die Position und Maße jedes sichtbaren Elements auf der Seite. Sobald eine Interaktion das DOM verändert oder CSS-Eigenschaften anfasst, die sich auf die Geometrie auswirken (width, height, margin, padding, top, left), muss der Browser das Layout neu berechnen, bevor er den aktualisierten Frame zeichnen kann.

Zwei Muster verlagern Layout-Berechnungen direkt in deinen Event-Handler. Dieses erzwungene Layout zählt zur Processing Time. Zum Presentation Delay zählt nur das Layout, das der Browser nach Abschluss deines Handlers ausführt:

Ein Forced Synchronous Layout entsteht, wenn JavaScript eine Layout-Eigenschaft (wie offsetHeight oder getBoundingClientRect()) abfragt, nachdem eine DOM-Änderung das Layout invalidiert hat. Der Browser muss das Layout synchron noch innerhalb deines Event-Handlers berechnen, um einen exakten Wert zurückzuliefern. Diese Layout-Arbeit wird Teil der Processing Time. Jedes nachfolgende Layout, das durch weitere DOM-Änderungen ausgelöst wird, fällt jedoch in den Presentation Delay.

Layout Thrashing entsteht, wenn du in einer Schleife wiederholt ins DOM schreibst und direkt danach Layout-Eigenschaften abfragst. Jeder Lesevorgang zwingt den Browser zur Layout-Neuberechnung; jeder Schreibvorgang invalidiert das Layout erneut. Das kann Dutzende oder Hunderte unnötige Layout-Berechnungen pro Interaktion auslösen. Hier ist ein Beispiel für Layout Thrashing und wie du es behebst:

// SCHLECHT: Layout Thrashing in einer Schleife
function resizeItems() {
  const items = document.querySelectorAll('.item');
  items.forEach(item => {
    // Lesen (erzwingt Layout)
    const parentWidth = item.parentElement.offsetWidth;
    // Schreiben (invalidiert Layout)
    item.style.width = parentWidth + 'px';
  });
}

// GUT: Erst alle Leseoperationen bündeln, dann alle Schreiboperationen
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';
  });
}

Client-seitiges Rendering in Single-Page-Applications

Das client-seitige Rendern von HTML kann den Presentation Delay massiv in die Höhe treiben – 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:

  1. Den Diffing-Algorithmus des Virtual DOM ausführen, um Änderungen zu ermitteln
  2. Die resultierenden DOM-Mutationen auf das reale DOM anwenden
  3. Style-Neuberechnungen und Layout für alle betroffenen Elemente anstoßen
  4. Den aktualisierten Frame zeichnen

In React-Anwendungen gehört der Reconciliation-Prozess des Virtual DOM zur Processing Time. Die daraus resultierenden DOM-Mutationen und deren Rendering-Kosten fallen jedoch in den Presentation Delay. Je mehr DOM-Knoten dein Komponentenbaum erzeugt, desto aufwendiger werden der Abgleich und die anschließende Rendering-Arbeit.

So reduzierst du diesen Aufwand in React- und Next.js-Anwendungen:

  • Nutze React.memo(), um unnötige Re-Renders von Child-Komponenten mit identischen Props zu verhindern.
  • Nutze useDeferredValue() für Werte, die teure Re-Renders auslösen, damit React dringendere Updates vorziehen kann.
  • Halte Komponentenbäume flach. Tief verschachtelte Hierarchien erzeugen ein tief verschachteltes DOM – das verteuert sowohl den Abgleich als auch das Rendering im Browser.
  • Setze Virtualisierungs-Bibliotheken (wie react-window oder @tanstack/react-virtual) für lange Listen ein, damit das DOM nur die tatsächlich sichtbaren Elemente enthält.

Presentation Delay reduzieren

DOM-Größe minimieren

Der größte Hebel für einen niedrigen Presentation Delay ist ein kleines DOM:

  • Entferne ungenutzte HTML-Elemente, besonders tief verschachtelte Wrapper-Divs.
  • Nutze Listen-Virtualisierung für lange Listen (rendere nur sichtbare Elemente plus einen kleinen Puffer).
  • Halte verschachtelte Strukturen so flach wie möglich.
  • Nutze CSS Grid und Flexbox für das Layout statt verschachtelter Divs.
// 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 Off-Screen-Inhalte lazy zu rendern

Die CSS-Eigenschaft content-visibility weist den Browser an, das Rendern von Inhalten außerhalb des Bildschirms zu überspringen, bis der Nutzer in deren Nähe scrollt. Das verringert den Rendering-Aufwand bei Interaktionen, da Style-Neuberechnungen und Layout auf den sichtbaren Teil der Seite begrenzt bleiben.

/* content-visibility auf Abschnitte unterhalb des Viewports anwenden */
.below-fold-section {
  content-visibility: auto;
  contain-intrinsic-size: auto 500px;
}

/* Auf einzelne Elemente in langen Listen anwenden */
.list-item {
  content-visibility: auto;
  contain-intrinsic-size: auto 80px;
}

Die Eigenschaft contain-intrinsic-size liefert eine geschätzte Höhe, damit der Browser die Scrollleiste korrekt berechnen kann, ohne den Inhalt vorab zu rendern. Das verhindert Layout Shifts, wenn der Nutzer scrollt und die Inhalte sichtbar werden.

Weitere CSS-Optimierungsstrategien zur Senkung des Rendering-Aufwands findest du in unserem Leitfaden: Ungenutztes CSS entfernen.

Layout-Arbeit bei Interaktionen minimieren

Setze bei Interaktionen bevorzugt auf CSS-Eigenschaften, die kein Layout auslösen. Eigenschaften wie transform und opacity verarbeitet der GPU-Compositor direkt – ganz ohne Layout oder Paint. Statt top, left, width oder height zu animieren, nutze transform: translate() und transform: scale(). Eine vollständige Liste aller CSS-Eigenschaften, die Layout auslösen, findest du im web.dev-Leitfaden zur Rendering Performance.

Nutze die CSS-Eigenschaft will-change, um dem Browser zu signalisieren, dass ein Element animiert wird. So kann der Browser eine eigene Compositor-Ebene für das Element erstellen und dessen Rendering vom Rest der Seite isolieren:

/* Elemente auf eine eigene Compositor-Ebene auslagern */
.animated-element {
  will-change: transform, opacity;
}

/* Sichtbarkeit mit opacity statt display umschalten */
.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 Presentation Delays erkennen

Um lange Presentation Delays zu identifizieren, nutzt du am besten den Performance-Profiler von Chrome. Öffne die DevTools (Strg+Umschalt+I), wechsle zum Performance-Tab, starte die Aufzeichnung und interagiere mit der Seite.

Anschließend kannst du die Timeline einer Interaktion analysieren und die einzelnen Phasen visualisieren – inklusive des Presentation Delay. Wenn du dir die Rendering-Updates nach Abschluss der Event-Handler ansiehst, erkennst du Engpässe sofort, die zu einem langen Presentation Delay führen. Achte in der Timeline auf große Blöcke für „Recalculate Style“, „Layout“ und „Paint“. Sie zeigen dir genau die Arbeit, die der Browser während der Presentation-Delay-Phase leistet.

Chrome DevTools performance timeline showing INP presentation delay phases with 20.584ms

Presentation Delay mit RUM-Daten identifizieren

Real User Monitoring (RUM) liefert Echtzeitdaten zu wichtigen Core-Web-Vitals-Metriken wie dem Interaction to Next Paint und dessen Teilphasen – einschließlich des Presentation Delay. Ein RUM-Tool wie CoreDash schlüsselt jede einzelne INP-Interaktion in ihre drei Phasen auf. So siehst du sofort, ob der Presentation Delay der Flaschenhals auf bestimmten Seiten oder bei bestimmten Nutzersegmenten ist.

Presentation Delay mit Long Animation Frames (LoAF) messen

Die Long-Animation-Frames-API (LoAF) zeigt dir genau, was Rendering-Verzögerungen bei Nutzerinteraktionen verursacht. Über die Timing-Daten der API trennst du die Processing Time sauber vom Presentation Delay und erkennst, welche Skripte das Rendering ausbremsen.

Die wichtigsten LoAF-Eigenschaften für den Presentation Delay sind:

  • renderStart: Zeitpunkt, an dem der Browser die Rendering-Phase gestartet hat (Style-Neuberechnung, Layout, Paint)
  • styleAndLayoutStart: Beginn der Style- und Layout-Berechnung
  • duration: Gesamtdauer des Long Animation Frame
  • blockingDuration: Zeitspanne, in der Skripte den Frame blockiert haben

LoAF funktioniert derzeit nur in Chromium-basierten Browsern (Chrome 123+). Für andere Browser nutzt du Traces im Performance-Panel der Chrome DevTools, um die Rendering-Arbeit zu analysieren.

Die Differenz zwischen dem Ende der Skriptausführung und dem Ende des Frames entspricht dem reinen Rendering-Aufwand – also dem Presentation Delay. So liest du diese Daten aus und loggst sie:

// Presentation Delay 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 und zeigen dir mit vollständiger Skript-Zuordnung, welche Skripte und DOM-Änderungen Verzögerungen beim Rendering verursachen.

Weitere INP-Phasen erkunden

Um deinen INP in den Griff zu bekommen, musst du auch die beiden anderen Phasen angehen:

  • Input Delay: Minimiere die Wartezeit, bevor Event-Handler ausgeführt werden. Der Input Delay ist meist die kürzeste Phase, schießt aber beim Laden der Seite nach oben, wenn der Main Thread überlastet ist.
  • Processing Time: Optimiere den Code deiner Event-Handler, 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: INP-Probleme aufspüren und beheben. Weitere Strategien zur Rendering-Optimierung findest du in unseren Anleitungen: Zu große DOM-Größe beheben und Ungenutztes CSS entfernen. Einen vollständigen Überblick bietet dir unsere INP-Übersichtsseite.

Arjen Karel

Brauchst du eine schnellere Website?

Ich bin Arjen und mache seit 17 Jahren langsame Websites schnell. Wenn du auf Probleme stößt, die du nicht selbst lösen kannst, schick mir deine URL und wir reden darüber.

Schick mir deine URL
Arjen Karel
Arjen Karel, Web-Performance-Consultant seit 2009

Warum funktioniert unser Fix nicht?

Manchmal liefert das CDN noch das alte HTML aus, oder der Fix steckt im Desktop-Template und Mobilgeräte nutzen ein anderes. Schick mir deine URL und das Problem, dann antworte ich mit ein paar Terminvorschlägen. Ich prüfe zuerst deine Field Data, dann arbeiten wir eine Stunde an deiner Website, und innerhalb eines Tages hast du meine Notizen schriftlich. 350 € zzgl. MwSt.

Schick mir deine URL

Kein Entwickler für den Fix? Ich mache die Arbeit selbst, auf einer Kopie deiner Website.