1. Einführung
Eine interaktive Demo und ein Codelab zum Messwert Interaction to Next Paint (INP).
Vorbereitung
- Kenntnisse in der HTML- und JavaScript-Entwicklung
- Empfohlen: INP-Dokumentation lesen.
Lerninhalte
- Wie sich das Zusammenspiel von Nutzerinteraktionen und der Art und Weise, wie Sie diese Interaktionen verarbeiten, auf die Reaktionsfähigkeit der Seite auswirkt.
- So lassen sich Verzögerungen reduzieren und vermeiden, um eine reibungslose Nutzererfahrung zu ermöglichen.
Voraussetzungen
- Ein Computer, auf dem Code von GitHub geklont und npm-Befehle ausgeführt werden können.
- Einen Texteditor.
- Eine aktuelle Version von Chrome, damit alle Interaktionsmessungen funktionieren.
2. Einrichten
Code abrufen und ausführen
Der Code befindet sich im Repository web-vitals-codelabs.
- Klonen Sie das Repository in Ihrem Terminal:
git clone https://github.com/GoogleChromeLabs/web-vitals-codelabs.git - Wechseln Sie in das geklonte Verzeichnis:
cd web-vitals-codelabs/understanding-inp - Abhängigkeiten installieren:
npm ci - Starten Sie den Webserver:
npm run start - Rufen Sie in Ihrem Browser http://localhost:5173/understanding-inp/ auf.
Übersicht über die App
Oben auf der Seite befindet sich ein Zähler für die Punktzahl und eine Schaltfläche Erhöhen. Ein klassisches Beispiel für Reaktivität und Reaktionsfähigkeit.

Unter der Schaltfläche sehen Sie vier Messwerte:
- INP: Der aktuelle INP-Wert, der in der Regel die schlechteste Interaktion darstellt.
- Interaktion: Die Punktzahl der letzten Interaktion.
- FPS: Die Frames pro Sekunde des Hauptthreads der Seite.
- Timer: Eine laufende Timer-Animation zur Visualisierung von Rucklern.
Die Einträge für FPS und Timer sind für die Messung von Interaktionen nicht erforderlich. Sie werden nur hinzugefügt, um die Visualisierung der Reaktionsfähigkeit zu erleichtern.
Jetzt ausprobieren
Klicken Sie auf die Schaltfläche Increment (Erhöhen) und sehen Sie zu, wie sich der Wert erhöht. Ändern sich die Werte für INP und Interaktion mit jedem Inkrement?
INP misst, wie lange es dauert, bis die Seite dem Nutzer die gerenderte Aktualisierung anzeigt, nachdem er mit ihr interagiert hat.
3. Interaktionen mit den Chrome-Entwicklertools messen
Öffnen Sie die Entwicklertools über das Menü Weitere Tools > Entwicklertools, indem Sie mit der rechten Maustaste auf die Seite klicken und Untersuchen auswählen oder indem Sie einen Tastenkürzel verwenden.
Wechseln Sie zum Bereich Leistung, in dem Sie Interaktionen messen können.

Erfassen Sie als Nächstes eine Interaktion im Bereich „Leistung“.
- Tippen Sie auf die Schaltfläche zum Aufzeichnen.
- Interagieren Sie mit der Seite (drücken Sie die Schaltfläche Increment).
- Beenden Sie die Aufnahme.
Auf der resultierenden Zeitachse finden Sie einen Track mit Interaktionen. Klicken Sie links auf das Dreieck, um den Bereich zu maximieren.

Es werden zwei Interaktionen angezeigt. Zoomen Sie auf das zweite Bild heran, indem Sie scrollen oder die W-Taste gedrückt halten.

Wenn Sie den Mauszeiger auf die Interaktion bewegen, sehen Sie, dass sie schnell war, keine Zeit für die Verarbeitungsdauer benötigt hat und nur eine minimale Zeit für die Eingabeverzögerung und Darstellungsverzögerung. Die genauen Zeitspannen hängen von der Geschwindigkeit Ihres Computers ab.
4. Lang andauernde Event-Listener
Öffnen Sie die Datei index.js und entfernen Sie die Kommentarzeichen vor der Funktion blockFor im Event-Listener.
Vollständiger Code: click_block.html
button.addEventListener('click', () => {
blockFor(1000);
score.incrementAndUpdateUI();
});
Speichern Sie die Datei. Der Server erkennt die Änderung und aktualisiert die Seite für Sie.
Versuchen Sie noch einmal, mit der Seite zu interagieren. Die Interaktionen werden jetzt deutlich langsamer ausgeführt.
Leistungsanalyse
Nehmen Sie eine weitere Aufzeichnung im Bereich „Leistung“ vor, um zu sehen, wie das dort aussieht.

Was früher eine kurze Interaktion war, dauert jetzt eine volle Sekunde.
Wenn Sie den Mauszeiger auf die Interaktion bewegen, sehen Sie, dass die Zeit fast vollständig für die „Verarbeitungsdauer“ aufgewendet wird. Das ist die Zeit, die für die Ausführung der Event-Listener-Callbacks benötigt wird. Da der blockierende blockFor-Aufruf vollständig innerhalb des Event-Listeners erfolgt, wird die Zeit dort verbracht.
5. Test: Verarbeitungsdauer
Probieren Sie verschiedene Möglichkeiten aus, die Arbeit des Event-Listeners neu anzuordnen, um die Auswirkungen auf INP zu sehen.
Benutzeroberfläche zuerst aktualisieren
Was passiert, wenn Sie die Reihenfolge der JS-Aufrufe ändern – zuerst die Benutzeroberfläche aktualisieren und dann blockieren?
Vollständiger Code: ui_first.html
button.addEventListener('click', () => {
score.incrementAndUpdateUI();
blockFor(1000);
});
Ist Ihnen aufgefallen, dass die Benutzeroberfläche früher angezeigt wurde? Wirkt sich die Reihenfolge auf INP-Werte aus?
Erstellen Sie einen Trace und untersuchen Sie die Interaktion, um festzustellen, ob es Unterschiede gab.
Listener trennen
Was passiert, wenn Sie die Arbeit in einen separaten Event-Listener verschieben? Aktualisieren Sie die Benutzeroberfläche in einem Event-Listener und blockieren Sie die Seite in einem separaten Listener.
Vollständiger Code: two_click.html
button.addEventListener('click', () => {
score.incrementAndUpdateUI();
});
button.addEventListener('click', () => {
blockFor(1000);
});
Wie sieht das jetzt im Bereich „Leistung“ aus?
Verschiedene Ereignistypen
Bei den meisten Interaktionen werden viele Arten von Ereignissen ausgelöst, von Zeiger- oder Tastaturereignissen bis hin zu Hover-, Fokus-/Unfokus- und synthetischen Ereignissen wie „beforechange“ und „beforeinput“.
Viele echte Seiten haben Listener für viele verschiedene Ereignisse.
Was passiert, wenn Sie die Ereignistypen für die Ereignis-Listener ändern? Ersetzen Sie beispielsweise einen der click-Event-Listener durch pointerup oder mouseup.
Vollständiger Code: diff_handlers.html
button.addEventListener('click', () => {
score.incrementAndUpdateUI();
});
button.addEventListener('pointerup', () => {
blockFor(1000);
});
Kein Update der Benutzeroberfläche
Was passiert, wenn Sie den Aufruf zum Aktualisieren der Benutzeroberfläche aus dem Ereignis-Listener entfernen?
Vollständiger Code: no_ui.html
button.addEventListener('click', () => {
blockFor(1000);
// score.incrementAndUpdateUI();
});
6. Verarbeitungsdauer von Testergebnissen
Leistungs-Trace: Benutzeroberfläche zuerst aktualisieren
Vollständiger Code: ui_first.html
button.addEventListener('click', () => {
score.incrementAndUpdateUI();
blockFor(1000);
});
Wenn Sie sich eine Aufzeichnung des Leistungsbereichs ansehen, in der auf die Schaltfläche geklickt wird, sehen Sie, dass sich die Ergebnisse nicht geändert haben. Obwohl eine Aktualisierung der Benutzeroberfläche vor dem blockierenden Code ausgelöst wurde, hat der Browser die Darstellung auf dem Bildschirm erst nach Abschluss des Event-Listeners aktualisiert. Die Interaktion hat also immer noch etwas mehr als eine Sekunde gedauert.

Leistungs-Trace: Separate Listener
Vollständiger Code: two_click.html
button.addEventListener('click', () => {
score.incrementAndUpdateUI();
});
button.addEventListener('click', () => {
blockFor(1000);
});
Auch hier gibt es funktional keinen Unterschied. Die Interaktion dauert weiterhin eine volle Sekunde.
Wenn Sie die Klickinteraktion vergrößern, sehen Sie, dass tatsächlich zwei verschiedene Funktionen als Ergebnis des click-Ereignisses aufgerufen werden.
Wie erwartet wird die erste Aufgabe – die Aktualisierung der Benutzeroberfläche – sehr schnell ausgeführt, während die zweite eine volle Sekunde dauert. Die Summe ihrer Auswirkungen führt jedoch zu derselben langsamen Interaktion für den Endnutzer.

Leistungs-Trace: verschiedene Ereignistypen
button.addEventListener('click', () => {
score.incrementAndUpdateUI();
});
button.addEventListener('pointerup', () => {
blockFor(1000);
});
Diese Ergebnisse sind sehr ähnlich. Die Interaktion dauert weiterhin eine volle Sekunde. Der einzige Unterschied besteht darin, dass der kürzere click-Listener, der nur die Benutzeroberfläche aktualisiert, jetzt nach dem blockierenden pointerup-Listener ausgeführt wird.

Leistungs-Trace: Keine Aktualisierung der Benutzeroberfläche
Vollständiger Code: no_ui.html
button.addEventListener('click', () => {
blockFor(1000);
// score.incrementAndUpdateUI();
});
- Der Wert wird nicht aktualisiert, die Seite aber schon.
- Animationen, CSS-Effekte, Standardaktionen für Webkomponenten (Formulareingabe), Texteingabe und Texthervorhebung werden weiterhin aktualisiert.
In diesem Fall wechselt die Schaltfläche beim Klicken in den aktiven Status und wieder zurück. Dazu muss der Browser die Seite neu rendern. Es gibt also weiterhin einen INP.
Da der Event-Listener den Hauptthread eine Sekunde lang blockiert hat, wodurch die Seite nicht gerendert werden konnte, dauert die Interaktion immer noch eine volle Sekunde.
Wenn Sie eine Aufzeichnung des Leistungspanels erstellen, wird die Interaktion nahezu identisch mit den vorherigen Interaktionen angezeigt.

Fazit
Jeder Code, der in einem beliebigen Ereignis-Listener ausgeführt wird, verzögert die Interaktion.
- Dazu gehören Listener, die über verschiedene Skripts registriert wurden, sowie Framework- oder Bibliothekscode, der in Listenern ausgeführt wird, z. B. eine Statusaktualisierung, die das Rendern einer Komponente auslöst.
- Nicht nur Ihr eigener Code, sondern auch alle Drittanbieter-Scripts.
Das ist ein häufiges Problem.
Schließlich gilt: Nur weil Ihr Code keinen Paint-Vorgang auslöst, heißt das nicht, dass kein Paint-Vorgang auf langsame Event-Listener wartet.
7. Test: Eingabeverzögerung
Was ist mit Code, der außerhalb von Event-Listenern lange ausgeführt wird? Beispiel:
- Wenn Sie ein spät ladendes
<script>hatten, das die Seite während des Ladevorgangs zufällig blockiert hat. - Ein API-Aufruf, z. B.
setInterval, der die Seite regelmäßig blockiert?
Entfernen Sie blockFor aus dem Event-Listener und fügen Sie es einem setInterval() hinzu:
Vollständiger Code: input_delay.html
setInterval(() => {
blockFor(1000);
}, 3000);
button.addEventListener('click', () => {
score.incrementAndUpdateUI();
});
Was ändert sich?
8. Ergebnisse des Tests zur Eingabeverzögerung
Vollständiger Code: input_delay.html
setInterval(() => {
blockFor(1000);
}, 3000);
button.addEventListener('click', () => {
score.incrementAndUpdateUI();
});
Wenn ein Schaltflächenklick aufgezeichnet wird, der zufällig während der Ausführung des blockierenden Tasks setInterval erfolgt, führt dies zu einer Interaktion mit langer Ausführungszeit, auch wenn in der Interaktion selbst keine blockierenden Arbeiten ausgeführt werden.
Diese langen Zeiträume werden oft als „Long Tasks“ bezeichnet.
Wenn Sie in den DevTools mit dem Mauszeiger auf die Interaktion zeigen, sehen Sie, dass die Interaktionszeit jetzt hauptsächlich auf die Eingabeverzögerung und nicht auf die Verarbeitungsdauer zurückzuführen ist.

Beachten Sie, dass sich dies nicht immer auf die Interaktionen auswirkt. Wenn Sie während der Ausführung der Aufgabe nicht klicken, haben Sie vielleicht Glück. Solche „zufälligen“ Nieser können sehr schwer zu debuggen sein, wenn sie nur manchmal Probleme verursachen.
Eine Möglichkeit, diese Probleme zu finden, besteht darin, lange Aufgaben (oder Long Animation Frames) und die Total Blocking Time zu messen.
9. Langsame Präsentation
Bisher haben wir uns die Leistung von JavaScript über Eingabeverzögerung oder Event-Listener angesehen. Was wirkt sich aber noch auf das Rendern des nächsten Paint aus?
Nun, die Seite mit teuren Effekten zu aktualisieren!
Auch wenn die Seiten schnell aktualisiert werden, muss der Browser möglicherweise viel Arbeit leisten, um sie zu rendern.