Interaktion für den nächsten Farbauftrag optimieren

Hier erfahren Sie, wie Sie den Messwert „Interaction to Next Paint“ Ihrer Website optimieren.

Veröffentlicht: 19. Mai 2023, zuletzt aktualisiert: 2. September 2025

Interaction to Next Paint (INP) ist ein stabiler Core Web Vital-Messwert, mit dem die Reaktionszeit einer Seite auf Nutzerinteraktionen insgesamt bewertet wird. Dazu wird die Latenz aller qualifizierten Interaktionen erfasst, die während des Besuchs eines Nutzers auf einer Seite stattfinden. Der endgültige INP-Wert ist die längste beobachtete Interaktion, wobei Ausreißer manchmal ignoriert werden.

Für eine gute Nutzerfreundlichkeit sollten Websites einen „Interaction to Next Paint“-Wert von höchstens 200 Millisekunden anstreben. Wenn ihr dafür sorgen wollt, dass ihr für die meisten eurer Nutzerinnen und Nutzer die empfohlenen Messwerte erreicht, genügt es, das 75. Perzentil aller Seitenaufrufe, aufgeschlüsselt nach Mobilgeräten und Desktop-Geräten, zu messen.

Gute INP-Werte liegen bei 200 Millisekunden oder weniger, schlechte Werte bei mehr als 500 Millisekunden. Alles dazwischen muss verbessert werden.
INP-Grenzwerte

Je nach Website gibt es möglicherweise nur wenige oder gar keine Interaktionen, z. B. Seiten, die hauptsächlich aus Text und Bildern mit wenigen oder gar keinen interaktiven Elementen bestehen. Bei Websites wie Texteditoren oder Spielen kann es Hunderte oder sogar Tausende von Interaktionen geben. In beiden Fällen ist die Nutzerfreundlichkeit bei einem hohen INP-Wert gefährdet.

Es erfordert Zeit und Mühe, den INP zu verbessern, aber die Belohnung ist eine bessere Nutzererfahrung. In diesem Leitfaden wird ein Weg zur Verbesserung des INP-Werts beschrieben.

Ursache für schlechten INP ermitteln

Bevor Sie langsame Interaktionen beheben können, benötigen Sie Daten, die Aufschluss darüber geben, ob der INP Ihrer Website schlecht ist oder verbessert werden muss. Sobald Sie diese Informationen haben, können Sie im Lab mit der Diagnose langsamer Interaktionen beginnen und eine Lösung erarbeiten.

Langsame Interaktionen im Feld finden

Idealerweise beginnen Sie mit der Optimierung des INP mit Felddaten. Im Idealfall liefern Felddaten eines RUM-Anbieters (Real User Monitoring) nicht nur den INP-Wert einer Seite, sondern auch Kontextdaten, die Aufschluss darüber geben, welche Interaktion für den INP-Wert verantwortlich war, ob die Interaktion während oder nach dem Laden der Seite stattgefunden hat, welche Art von Interaktion (Klick, Tastendruck oder Tippen) es war und andere wertvolle Informationen.

Wenn Sie keinen RUM-Anbieter für Felddaten nutzen, wird im Leitfaden zu INP-Felddaten empfohlen, PageSpeed Insights zu verwenden, um die Daten des Chrome User Experience Report (CrUX) aufzurufen und so die Lücken zu füllen. CrUX ist das Google-Dataset des Core Web Vitals-Programms und bietet eine allgemeine Zusammenfassung der Messwerte für Millionen von Websites, einschließlich INP. CrUX liefert jedoch oft nicht die Kontextdaten, die Sie von einem RUM-Anbieter erhalten würden, um Probleme zu analysieren. Daher empfehlen wir Websites nach wie vor, nach Möglichkeit einen RUM-Anbieter zu verwenden oder eine eigene RUM-Lösung zu implementieren, um die in CrUX verfügbaren Daten zu ergänzen.

Langsame Interaktionen im Lab diagnostizieren

Idealerweise sollten Sie mit dem Testen im Labor beginnen, sobald Sie Felddaten haben, die auf langsame Interaktionen hindeuten. Wenn keine Felddaten vorhanden sind, gibt es einige Strategien, um langsame Interaktionen im Labor zu identifizieren. Dazu gehören das Verfolgen gängiger User-Flows und das Testen von Interaktionen währenddessen sowie das Interagieren mit der Seite während des Ladens, wenn der Hauptthread oft am stärksten ausgelastet ist. So lassen sich langsame Interaktionen während dieses entscheidenden Teils der Nutzererfahrung identifizieren.

Interaktionen optimieren

Nachdem Sie eine langsame Interaktion identifiziert haben und sie im Lab manuell reproduzieren können, besteht der nächste Schritt darin, sie zu optimieren.

Interaktionen können in drei Unterbereiche unterteilt werden:

  1. Die Eingabeverzögerung, die beginnt, wenn der Nutzer eine Interaktion mit der Seite initiiert, und endet, wenn die Ereignis-Callbacks für die Interaktion ausgeführt werden.
  2. Die Verarbeitungsdauer, die sich aus der Zeit zusammensetzt, die für die Ausführung von Ereignis-Callbacks benötigt wird.
  3. Die Präsentationsverzögerung, also die Zeit, die der Browser benötigt, um den nächsten Frame mit dem visuellen Ergebnis der Interaktion darzustellen.
Beispiel für eine Interaktion im Hauptthread. Der Nutzer nimmt eine Eingabe vor, während blockierende Aufgaben ausgeführt werden. Die Eingabe wird verzögert, bis diese Aufgaben abgeschlossen sind. Danach werden die Event-Handler für „pointerup“, „mouseup“ und „click“ ausgeführt. Anschließend werden Rendering- und Painting-Arbeiten gestartet, bis der nächste Frame angezeigt wird.
Der Ablauf einer Interaktion. Eine Eingabeverzögerung tritt auf, bis die Ereignis-Handler ausgeführt werden. Dies kann durch Faktoren wie lange Aufgaben im Hauptthread verursacht werden. Anschließend werden die Event-Handler-Callbacks der Interaktion ausgeführt und es kommt zu einer Verzögerung, bevor der nächste Frame angezeigt wird.

Die Summe dieser drei Teilbereiche ist die gesamte Interaktionslatenz. Jeder einzelne Teil einer Interaktion trägt zur Gesamtlatenz der Interaktion bei. Daher ist es wichtig zu wissen, wie Sie jeden Teil der Interaktion so optimieren können, dass er so schnell wie möglich ausgeführt wird.

Eingabeverzögerung erkennen und reduzieren

Wenn ein Nutzer mit einer Seite interagiert, ist der erste Teil dieser Interaktion die Eingabeverzögerung. Je nach anderen Aktivitäten auf der Seite können Eingabeverzögerungen erheblich sein. Das kann an Aktivitäten im Hauptthread (z. B. durch das Laden, Parsen und Kompilieren von Scripts), an der Verarbeitung von Abrufen, an Timer-Funktionen oder sogar an anderen Interaktionen liegen, die in schneller Folge auftreten und sich gegenseitig überschneiden.

Unabhängig von der Ursache der Eingabeverzögerung einer Interaktion sollten Sie die Eingabeverzögerung auf ein Minimum reduzieren, damit Interaktionen so schnell wie möglich Ereignis-Callbacks ausführen können.

Die Beziehung zwischen der Skriptauswertung und Long Tasks beim Start

Ein wichtiger Aspekt der Interaktivität im Seitenlebenszyklus ist der Start. Beim Seitenaufbau wird eine Seite zuerst gerendert. Es ist jedoch wichtig, zu beachten, dass eine Seite, die gerendert wurde, nicht unbedingt vollständig geladen ist. Je nachdem, wie viele Ressourcen eine Seite benötigt, um vollständig funktionsfähig zu sein, versuchen Nutzer möglicherweise, mit der Seite zu interagieren, während sie noch geladen wird.

Ein Faktor, der die Eingabeverzögerung einer Interaktion während des Seitenaufbaus verlängern kann, ist die Skriptauswertung. Nachdem eine JavaScript-Datei aus dem Netzwerk abgerufen wurde, muss der Browser noch einige Schritte ausführen, bevor das JavaScript ausgeführt werden kann. Dazu gehören das Parsen eines Skripts, um die Syntax zu prüfen, das Kompilieren in Bytecode und schließlich die Ausführung.

Je nach Größe eines Scripts kann diese Arbeit zu langen Aufgaben im Hauptthread führen, was die Reaktion des Browsers auf andere Nutzerinteraktionen verzögert. Damit Ihre Seite während des Ladens auf Nutzereingaben reagiert, sollten Sie wissen, wie Sie die Wahrscheinlichkeit von Long Tasks während des Ladens der Seite verringern können, damit die Seite schnell reagiert.

Ereignis-Callbacks optimieren

Die Eingabeverzögerung ist nur der erste Teil dessen, was INP misst. Außerdem müssen Sie dafür sorgen, dass die Ereignis-Callbacks, die als Reaktion auf eine Nutzerinteraktion ausgeführt werden, so schnell wie möglich abgeschlossen werden können.

Häufig an den Hauptthread übergeben

Der beste allgemeine Rat zur Optimierung von Ereignis-Callbacks ist, so wenig Arbeit wie möglich darin zu erledigen. Ihre Interaktionslogik kann jedoch komplex sein und Sie können die Arbeit der Nutzer möglicherweise nur geringfügig reduzieren.

Wenn dies auf Ihre Website zutrifft, können Sie als Nächstes versuchen, die Arbeit in Ereignis-Callbacks in separate Aufgaben aufzuteilen. So wird verhindert, dass die gesamte Arbeit zu einem Long Task wird, der den Hauptthread blockiert. Andere Interaktionen, die sonst auf den Hauptthread warten müssten, können so früher ausgeführt werden.

setTimeout ist eine Möglichkeit, Aufgaben aufzuteilen, da der übergebene Callback in einer neuen Aufgabe ausgeführt wird. Sie können setTimeout allein verwenden oder die Verwendung in eine separate Funktion abstrahieren, um die Übergabe ergonomischer zu gestalten.

Ein wahlloses Yielding ist besser als gar kein Yielding. Es gibt jedoch eine differenziertere Methode, um dem Hauptthread die Kontrolle zu übergeben. Dabei wird die Kontrolle nur unmittelbar nach einem Ereignis-Callback übergeben, der die Benutzeroberfläche aktualisiert, damit die Rendering-Logik früher ausgeführt werden kann.

Yielding, damit Rendering-Arbeiten früher ausgeführt werden können

Eine fortgeschrittenere Technik besteht darin, den Code in Ihren Event-Callbacks so zu strukturieren, dass nur die Logik ausgeführt wird, die für die Anwendung visueller Updates für den nächsten Frame erforderlich ist. Alles andere kann auf eine nachfolgende Aufgabe verschoben werden. Dadurch bleiben Callbacks nicht nur leicht und flexibel, sondern es wird auch die Renderingzeit für Interaktionen verbessert, da visuelle Aktualisierungen nicht durch Ereignis-Callback-Code blockiert werden können.

Stellen Sie sich beispielsweise einen Rich-Text-Editor vor, der Text während der Eingabe formatiert, aber auch andere Aspekte der Benutzeroberfläche als Reaktion auf das, was Sie geschrieben haben, aktualisiert (z. B. Wortanzahl, Hervorhebung von Rechtschreibfehlern und anderes wichtiges visuelles Feedback). Außerdem muss die Anwendung möglicherweise speichern, was Sie geschrieben haben, damit Sie Ihre Arbeit nicht verlieren, wenn Sie die Anwendung verlassen und zurückkehren.

In diesem Beispiel müssen die folgenden vier Dinge als Reaktion auf die vom Nutzer eingegebenen Zeichen passieren. Allerdings muss nur der erste Punkt erledigt werden, bevor der nächste Frame angezeigt wird.

  1. Aktualisieren Sie das Textfeld mit dem, was der Nutzer eingegeben hat, und wenden Sie die erforderliche Formatierung an.
  2. Aktualisieren Sie den Teil der Benutzeroberfläche, in dem die aktuelle Wortzahl angezeigt wird.
  3. Führen Sie eine Logik aus, um nach Rechtschreibfehlern zu suchen.
  4. Die letzten Änderungen speichern (entweder lokal oder in einer Remote-Datenbank).

Der Code dafür könnte in etwa so aussehen:

textBox.addEventListener('input', (inputEvent) => {
  // Update the UI immediately, so the changes the user made
  // are visible as soon as the next frame is presented.
  updateTextBox(inputEvent);

  // Use `setTimeout` to defer all other work until at least the next
  // frame by queuing a task in a `requestAnimationFrame()` callback.
  requestAnimationFrame(() => {
    setTimeout(() => {
      const text = textBox.textContent;
      updateWordCount(text);
      checkSpelling(text);
      saveChanges(text);
    }, 0);
  });
});

Die folgende Visualisierung zeigt, wie das Verschieben von nicht kritischen Aktualisierungen auf den nächsten Frame die Verarbeitungsdauer und damit die Gesamtlatenz der Interaktion reduzieren kann.

Darstellung einer Tastaturinteraktion und nachfolgender Aufgaben in zwei Szenarien. In der oberen Abbildung werden die renderkritische Aufgabe und alle nachfolgenden Hintergrundaufgaben synchron ausgeführt, bis die Möglichkeit besteht, einen Frame zu präsentieren. In der Abbildung unten wird die renderkritische Arbeit zuerst ausgeführt und dann an den Hauptthread übergeben, damit ein neuer Frame früher dargestellt werden kann. Die Hintergrundaufgaben werden danach ausgeführt.
Klicken Sie auf die Abbildung, um eine hochauflösende Version zu sehen.

Die Verwendung von setTimeout() innerhalb eines requestAnimationFrame()-Aufrufs im vorherigen Codebeispiel ist zwar etwas ungewöhnlich, aber eine effektive Methode, die in allen Browsern funktioniert, um zu verhindern, dass nicht kritischer Code den nächsten Frame blockiert.

Layout-Thrashing vermeiden

Layout-Thrashing, manchmal auch als erzwungenes synchrones Layout bezeichnet, ist ein Rendering-Leistungsproblem, bei dem das Layout synchron erfolgt. Es tritt auf, wenn Sie Stile in JavaScript aktualisieren und sie dann in derselben Aufgabe lesen. In JavaScript gibt es viele Eigenschaften, die zu Layout-Thrashing führen können.

Eine Visualisierung von Layout-Thrashing, wie sie im Bereich „Leistung“ der Chrome-Entwicklertools angezeigt wird.
Ein Beispiel für Layout-Thrashing, wie es im Bereich „Leistung“ der Chrome-Entwicklertools angezeigt wird. Rendering-Aufgaben, die Layout-Thrashing beinhalten, werden mit einem roten Dreieck in der oberen rechten Ecke des Teils des Aufrufstapels gekennzeichnet, der oft mit Stil neu berechnen oder Layout beschriftet ist.

Layout-Thrashing ist ein Leistungsengpass, da der Browser durch das Aktualisieren von Stilen und das sofortige Anfordern der Werte dieser Stile in JavaScript gezwungen wird, synchrone Layoutarbeiten auszuführen, die er sonst später asynchron hätte ausführen können, nachdem die Ereignis-Callbacks abgeschlossen sind.

Verzögerung bei der Präsentation minimieren

Die Präsentationsverzögerung einer Interaktion umfasst die Zeitspanne zwischen dem Ende der Ereignis-Callbacks einer Interaktion und dem Zeitpunkt, an dem der Browser den nächsten Frame rendern kann, der die resultierenden visuellen Änderungen zeigt.

DOM-Größe minimieren

Wenn das DOM einer Seite klein ist, wird das Rendering normalerweise schnell abgeschlossen. Wenn DOMs jedoch sehr groß werden, nimmt der Rendering-Aufwand mit zunehmender DOM-Größe tendenziell zu. Die Beziehung zwischen Rendering-Aufwand und DOM-Größe ist nicht linear, aber große DOMs erfordern mehr Rendering-Aufwand als kleine DOMs. Ein großes DOM ist in zwei Fällen problematisch:

  1. Beim ersten Rendern der Seite, wenn ein großes DOM viel Arbeit erfordert, um den Anfangszustand der Seite zu rendern.
  2. Als Reaktion auf eine Nutzerinteraktion, bei der ein großes DOM dazu führen kann, dass Rendering-Updates sehr aufwendig sind und der Browser daher länger braucht, um den nächsten Frame darzustellen.

Beachten Sie, dass es Fälle gibt, in denen große DOMs nicht wesentlich reduziert werden können. Es gibt zwar Ansätze, mit denen Sie die DOM-Größe reduzieren können, z. B. durch Vereinfachen des DOM oder Hinzufügen von Elementen zum DOM während Nutzerinteraktionen, um die anfängliche DOM-Größe gering zu halten. Diese Techniken sind jedoch nur begrenzt wirksam.

content-visibility verwenden, um Elemente außerhalb des Bildschirms verzögert zu rendern

Eine Möglichkeit, sowohl den Renderingaufwand beim Seitenaufbau als auch den Renderingaufwand als Reaktion auf Nutzerinteraktionen zu begrenzen, besteht darin, die CSS-Property content-visibility zu verwenden. Dadurch werden Elemente erst dann gerendert, wenn sie sich dem Darstellungsbereich nähern. Es kann zwar etwas Übung erfordern, content-visibility effektiv zu nutzen, aber es lohnt sich, wenn dadurch die Renderingzeit verkürzt und der INP-Wert Ihrer Seite verbessert wird.

Beachten Sie die Leistungskosten beim Rendern von HTML mit JavaScript.

Wo HTML ist, gibt es auch HTML-Parsing. Nachdem der Browser das HTML-Parsing in ein DOM abgeschlossen hat, muss er Stile darauf anwenden, Layoutberechnungen durchführen und dieses Layout anschließend rendern. Diese Kosten sind unvermeidlich, aber wie Sie HTML rendern, ist entscheidend.

Wenn der Server HTML sendet, kommt es als Stream im Browser an. Streaming bedeutet, dass die HTML-Antwort vom Server in Blöcken ankommt. Der Browser optimiert die Verarbeitung eines Streams, indem er Teile des Streams schrittweise parst, sobald sie eintreffen, und sie nach und nach rendert. Das ist eine Leistungsoptimierung, da der Browser während des Seitenaufbaus regelmäßig und automatisch implizit die Kontrolle abgibt. Das ist kostenlos.

Beim ersten Besuch einer Website wird immer etwas HTML-Code geladen. Ein gängiger Ansatz besteht darin, mit einer minimalen Menge an HTML-Code zu beginnen und dann JavaScript zu verwenden, um den Inhaltsbereich zu füllen. Nachfolgende Aktualisierungen dieses Inhaltsbereichs erfolgen ebenfalls als Ergebnis von Nutzerinteraktionen. Dies wird normalerweise als Single-Page-Anwendungsmodell (SPA) bezeichnet. Ein Nachteil dieses Musters ist, dass beim Rendern von HTML mit JavaScript auf dem Client nicht nur die Kosten für die JavaScript-Verarbeitung zur Erstellung dieses HTML-Codes anfallen, sondern der Browser auch nicht nachgibt, bis er das Parsen und Rendern dieses HTML-Codes abgeschlossen hat.

Es ist jedoch wichtig, daran zu denken, dass auch bei Websites, die keine SPAs sind, wahrscheinlich ein gewisses Maß an HTML-Rendering über JavaScript als Ergebnis von Interaktionen erfolgt. Das ist im Allgemeinen in Ordnung, solange Sie nicht große Mengen an HTML auf dem Client rendern, was die Darstellung des nächsten Frames verzögern kann. Es ist jedoch wichtig, die Auswirkungen dieses Ansatzes zum Rendern von HTML im Browser auf die Leistung zu verstehen und zu wissen, wie sich das Rendern von viel HTML mit JavaScript auf die Reaktionsfähigkeit Ihrer Website auf Nutzereingaben auswirken kann.

Fazit

Die Verbesserung des INP Ihrer Website ist ein iterativer Prozess. Wenn Sie eine langsame Interaktion im Feld beheben, ist die Wahrscheinlichkeit groß, dass Sie – insbesondere wenn Ihre Website viele interaktive Elemente enthält – weitere langsame Interaktionen finden, die Sie ebenfalls optimieren müssen.

Der Schlüssel zur Verbesserung des INP ist Ausdauer. Mit der Zeit können Sie die Reaktionsfähigkeit Ihrer Seite so verbessern, dass Nutzer mit der Nutzerfreundlichkeit zufrieden sind. Wenn Sie neue Funktionen für Ihre Nutzer entwickeln, müssen Sie wahrscheinlich auch die Interaktionen für diese Funktionen optimieren. Es wird Zeit und Mühe kosten, aber es lohnt sich.