Ursachen für schlechten INP ermitteln

Eine schlechte Reaktionsfähigkeit auf Interaktionen führt zu einem schlechten Eindruck, dass eine Seite langsam oder sogar vollständig fehlerhaft ist. Interaction to Next Paint (INP) ist ein Messwert, der auf der Event Timing API basiert. Dabei wird die schlechteste Interaktion (abzüglich einiger Ausreißer) als Maß für die Reaktionsfähigkeit der Seite gemessen.

Die Ursachen für eine nicht reagierende Webseite zu ermitteln, kann schwierig sein, insbesondere weil sie von Nutzerinteraktionen und Umgebungsbedingungen wie Gerätefunktionen und Netzwerkbedingungen abhängen. Das macht die Diagnose im Vergleich zu einem wiederholbaren und vorhersehbaren Szenario wie dem Seitenaufbau noch schwieriger. In Labordaten wird nur eine kleine Teilmenge realer Nutzerszenarien abgebildet. Daher ist es wichtig, die Ursachen für einen langsamen INP im Feld zu messen.

Mit der Event Timing API kann die INP-Dauer in drei Unterteile aufgeteilt werden: Eingabeverzögerung (Verarbeitung, die bereits stattfindet, wenn die Interaktion erfolgt), Verarbeitungsdauer (Verzögerungen, die direkt auf die Interaktion zurückzuführen sind) und Präsentationsverzögerung (Verzögerungen, die auf das Rendern des nächsten Frames nach der Interaktion zurückzuführen sind). So lässt sich feststellen, ob das Problem in anderem Code, im JavaScript-Code der Interaktion oder in der Browserverarbeitung von Rendering-Updates liegt, anstatt direkt zum Interaktionscode zu springen.

Es ist möglich, weitere Informationen zu JavaScript, zur Neuberechnung von Stilen und zur Layoutarbeit zu erhalten, die eine Interaktion verzögern. Ein vollständiger Leistungs-Trace mit der JS Self-Profiling API ist eine aufwendige Lösung, die zu Leistungsproblemen führen kann. Die Long Animation Frames API ist eine einfache API, mit der sich im Feld langsam laufendes JavaScript identifizieren und zwischen den Kosten für die Neuberechnung von Stilen und dem Layout während INP-Interaktionen unterscheiden lässt:

  • Erzwungener Stil und erzwungenes Layout auf Skriptebene (forcedStyleDuration und forcedLayoutDuration): Meldet synchrone Stilneuberechnungen (z. B. Aufruf von getComputedStyle() nach DOM-Mutationen) und erzwungene Layouts/Reflows (z. B. Lesen von getBoundingClientRect() oder offsetWidth nach Mutationen) innerhalb eines laufenden Skripts während der Eingabeverzögerung oder der Verarbeitungsdauer.
  • Rendering-Stil und Layout auf Frame-Ebene (styleDuration und layoutDuration): Hier wird die Zeit angegeben, die für die Neuberechnung von Stilen im Vergleich zur Aktualisierung des Layouts während der Rendering-Aktualisierung des Frames aufgewendet wurde. Das kann helfen, eine hohe Präsentationsverzögerung zu erklären.

Es ist wichtig, die Neuberechnung von Stilen vom Layout zu unterscheiden, da sie unterschiedliche Ursachen und Lösungen haben: Eine hohe Dauer der Stilberechnung deutet auf einen aufwendigen Abgleich von CSS-Selektoren oder eine umfassende Stil-Invalidierung hin (behebbar durch Vereinfachung von Selektoren oder Reduzierung des Regelumfangs). Eine hohe Dauer der Layoutberechnung deutet dagegen auf aufwendige Geometrieberechnungen oder synchrones Layout-Thrashing hin (behebbar durch Batching von DOM-Lesevorgängen vor Schreibvorgängen, Vereinfachung der DOM-Struktur oder Verwendung von CSS-Containment).

Implementierung

Die Berechnung des INP aus der Event Timing API ist kompliziert und hat mehrere Nuancen. Wir empfehlen, ein RUM-Tool oder eine RUM-Bibliothek zu verwenden, um diese Daten zu erfassen.

web-vitals ist eine Open-Source-Bibliothek von Google, die die Core Web Vitals einschließlich INP berechnet und auch Unterteile und Daten zu langen Animationsframes für die INP-Interaktion enthält.

Zuordnungen für INP-Interaktionen mit der web-vitals-Bibliothek abrufen

Die web-vitals-Bibliothek ist eine kleine Bibliothek, mit der Core Web Vitals und andere Leistungsmesswerte gemessen werden. Mit der Funktion onINP() lässt sich die langsamste Interaktion ermitteln. Sie enthält Informationen zu den INP-Unterteilen, zu Skripts, die während der Interaktion ausgeführt wurden, sowie zu Stil- und Layoutdauern, die über die Long Animation Frames API abgerufen werden.

// Use the attribution build to get Long Animation Frame data
// alongside the INP metric value.
import { onINP } from 'web-vitals/attribution';

onINP((metric) => {
  const { attribution } = metric;
  const longestScript = attribution.longestScript;

  // Sum rendering-phase style and layout durations across all LoAF entries
  // intersecting the INP interaction (primarily explains presentationDelay).
  let renderStyleDuration = 0;
  let renderLayoutDuration = 0;
  for (const entry of attribution.longAnimationFrameEntries) {
    renderStyleDuration += entry.styleDuration ?? 0;
    renderLayoutDuration += entry.layoutDuration ?? 0;
  }

  // Beacon script, style, and layout attribution for the INP interaction,
  // so you can identify the root cause in production.
  navigator.sendBeacon(
    '/analytics',
    JSON.stringify({
      name: 'INP',
      value: metric.value,
      // These fields give the INP subparts:
      inputDelay: attribution.inputDelay,
      presentationDelay: attribution.presentationDelay,
      processingDuration: attribution.processingDuration,
      interactionTarget: attribution.interactionTarget,
      // These fields identify which script function was responsible
      // for the longest processing during the INP interaction.
      invokerType: longestScript?.entry?.invokerType,
      sourceURL: longestScript?.entry?.sourceURL,
      sourceFunctionName: longestScript?.entry?.sourceFunctionName,
      sourceCharPosition: longestScript?.entry?.sourceCharPosition,
      // subpart indicates which phase (input delay, processing, or
      // presentation delay) the longest script overlapped with most.
      subpart: longestScript?.subpart,
      intersectingDuration: longestScript?.intersectingDuration,
      // Synchronous style and layout work forced inside the longest script
      // (with forcedStyleAndLayoutDuration as a combined fallback):
      forcedStyleDuration: longestScript?.entry?.forcedStyleDuration,
      forcedLayoutDuration: longestScript?.entry?.forcedLayoutDuration,
      forcedStyleAndLayoutDuration: longestScript?.entry?.forcedStyleAndLayoutDuration,
      // Rendering-phase style and layout work across the interaction's frames
      // (with totalStyleAndLayoutDuration as a combined fallback):
      renderStyleDuration,
      renderLayoutDuration,
      totalStyleAndLayoutDuration: attribution.totalStyleAndLayoutDuration
    })
  );
});

Best Practices

  • DO use INP subparts initially to identify whether the delay is already running JavaScript (input delay), the event handlers JavaScript for the interaction (processing duration), or the subsequent rendering (presentation delay).
  • VERSUCHEN SIE, das JavaScript zu identifizieren, das die größten Blockierungen verursacht, insbesondere bei der Eingabeverzögerung und der Verarbeitungsdauer.
  • DO: Unterscheiden Sie bei der Diagnose einer hohen Verarbeitungsdauer oder Präsentationsverzögerung zwischen der Neuberechnung des Stils (styleDuration, forcedStyleDuration) und dem Layout (layoutDuration, forcedLayoutDuration). Hohe Stilzeiten deuten auf komplexe CSS-Selektoren oder umfassende Invalidierungen hin, während hohe Layoutzeiten auf Engpässe bei der DOM-Geometrie oder synchrones Layout-Thrashing hinweisen.
  • EMPFOHLEN: Verwenden Sie die Long Animation Frames API, um diese zusätzlichen Details bereitzustellen, anstatt Alternativen wie die JS Self-Profiling API, die einen höheren Laufzeitaufwand verursacht.
  • DO use the web-vitals library if no other RUM solution is in place. Es kann die INP-Interaktion identifizieren und enthält Informationen zu den Unterteilen und den Skripts, die während der Interaktion ausgeführt wurden (mithilfe der Long Animation Frames API).
  • DO beacon back the required information to an analytics service rather than just log it locally.

Browserunterstützung und Fallback-Strategien

Die Event Timing API ist in den meisten modernen Browsern verfügbar und wird benötigt, um den INP und die INP-Unterkomponenten zu berechnen. In Browsern, die diese API nicht unterstützen, kann der INP nicht gemessen werden.

Die Long Animation Frames API bietet optionale, zusätzliche Details. Sie kann ohne Fallbacks verwendet werden. In den meisten Fällen gelten die ermittelten Optimierungsmöglichkeiten auch für andere Browser.

Wenn Ihr Baseline-Ziel die Long Animation Frames API (long-animation-frames) unterstützt, aber keine separaten Attribute für die Stil- und Layoutdauer (styleDuration und layoutDuration für PerformanceLongAnimationFrameTiming oder forcedStyleDuration und forcedLayoutDuration für PerformanceScriptTiming), greifen Sie auf die kombinierten Stil- und Layoutzeiten zurück:

  • Verwenden Sie script.forcedStyleAndLayoutDuration für PerformanceScriptTiming für synchrone erzwungene Stil- und Layoutarbeiten in Skripts.
  • Verwenden Sie metric.attribution.totalStyleAndLayoutDuration in web-vitals/attribution (oder berechnen Sie (entry.paintTime || entry.startTime + entry.duration) - entry.styleAndLayoutStart für jeden PerformanceLongAnimationFrameTiming-Eintrag) für kombinierte Stil- und Layoutarbeiten.