INP in Angular messen und optimieren | Core Web Vitals
Interaction to Next Paint in Angular richtig messen und optimieren: Schwellenwerte, DevTools, Zoneless, OnPush, @defer und Web Worker.

Interaction to Next Paint (INP) hat FID am 12. März 2024 als Core Web Vital abgelöst. Dieser Technikzeitpunkt ist nicht das Publikationsdatum: Der Artikel erschien am 20. März 2026 und wurde am 13. August 2026 fachlich aktualisiert. Ein guter INP-Wert liegt bei höchstens 200 ms im 75. Perzentil. Für Angular sind vor allem kurze Event-Handler, gezielte Change Detection und entkoppelte schwere Arbeit relevant.
Was sich im März 2024 geändert hat: FID ist weg
Seit März 2024 gilt: First Input Delay (FID) ist Geschichte. Interaction to Next Paint (INP) ist das neue Core Web Vital für Interaktivität — und es misst etwas fundamental anderes.
FID maß nur die Verzögerung bis zur ersten Eingabeverarbeitung. INP misst die gesamte Latenz jeder Interaktion auf der Seite: die Zeit vom Klick oder Tastendruck bis zum nächsten sichtbaren Frame im Browser. Das ist deutlich strenger.

Felddaten und Labormessungen beantworten unterschiedliche Fragen: Chrome UX Report und Search Console zeigen reale Nutzung über Zeit, während DevTools und Lighthouse einzelne reproduzierbare Abläufe analysieren. Deshalb sollte eine Optimierung nie aus einer isolierten Labormessung abgeleitet werden.
Was ist INP genau?
INP steht für Interaction to Next Paint. Der Wert misst die Zeit vom Beginn einer Benutzerinteraktion (Klick, Touch, Tastendruck) bis zu dem Moment, an dem der Browser den nächsten Frame malt.
- Input Delay — Zeit bis der Event Handler startet (blockiert durch anderen JS-Code auf dem Haupt-Thread)
- Processing Time — Zeit, die der Event Handler selbst benötigt
- Presentation Delay — Zeit bis das Rendering abgeschlossen ist
Für die Feldbewertung zählt der 75.-Perzentil-Wert der Seitenaufrufe, getrennt nach Mobilgeräten und Desktop. Innerhalb eines Seitenaufrufs repräsentiert INP annähernd die langsamste qualifizierte Interaktion; Ausreißer werden bei vielen Interaktionen begrenzt.
Schwellenwerte
Unter 200 ms gilt als gut. Werte zwischen 200–500 ms signalisieren Verbesserungsbedarf. Über 500 ms ist schlecht — hier muss sofort gehandelt werden.
INP messen: Die richtigen Tools
Bevor optimiert wird, muss gemessen werden. Es gibt mehrere Ansätze, die sich ergänzen.
Chrome DevTools — Performance Panel
Das Performance Panel zeigt INP-Kandidaten direkt an. Seit Chrome 122 wird INP als eigenständige Metrik hervorgehoben.
- DevTools öffnen → Performance-Tab
- Seite neu laden und mit der App interagieren
- Aufnahme stoppen → "Interactions"-Lane prüfen
- Lange Interaktionen (orange/rot markiert) identifizieren
web-vitals.js direkt einbinden
Für Real User Monitoring (RUM) in der eigenen App:
import { onINP } from 'web-vitals';
onINP(({ value, rating, entries }) => {
console.log(`INP: ${value}ms (${rating})`);
// An eigenen Analytics-Endpoint senden
sendToAnalytics({ metric: 'INP', value, rating });
});Warum Angular mit Zone.js anfällig ist
Ältere Angular-Anwendungen nutzen häufig Zone.js für Change Detection. Zone.js patcht verbreitete asynchrone Browser-APIs und signalisiert Angular nach Tasks, dass Anwendungszustand verändert sein könnte.
Das Problem ist nicht, dass Zone.js selbst DOM-Updates erzeugt. Es kann jedoch häufiger Anwendungssynchronisation anstoßen als nötig. Wie teuer das wird, hängt von Komponentenbaum, Change-Detection-Strategie und der eigentlichen Arbeit im Event-Handler ab.
[Benutzerinteraktion]
→ Zone.js plant Anwendungssynchronisation
→ Angular durchläuft die relevanten Views
→ geänderte Bindings werden aktualisiert
→ Browser malt den nächsten FrameOnPush kann Teilbäume überspringen; Signals benachrichtigen Angular gezielt über verwendete Zustände. Zoneless entfernt Zone.js als globalen Task-Trigger, ersetzt aber weder saubere Zustandsgrenzen noch die Messung konkreter Interaktionen.

Optimierung 1: Zoneless Change Detection
Seit Angular 20.2 ist Zoneless als stable markiert — seit Angular 21 ist es der Standard für neue Projekte.
In Angular 21 ist Zoneless für neue Anwendungen der Standard. Bestehende Angular-20-Anwendungen aktivieren es mit dem stabilen Provider; bei Angular 21 darf provideZoneChangeDetection() die Voreinstellung nicht wieder überschreiben:
// Angular 20: app.config.ts
import { provideZonelessChangeDetection } from '@angular/core';
export const appConfig: ApplicationConfig = {
providers: [provideZonelessChangeDetection()]
};
// Angular 21+: Zoneless ist Standard.
// Danach zone.js aus build/test-Polyfills und Abhängigkeiten entfernen.Zoneless plant Change Detection über konkrete Angular-Benachrichtigungen, etwa aktualisierte Signals, Template-Listener, gesetzte Inputs oder markForCheck(). Ob INP dadurch sinkt, muss für dieselbe Interaktion vor und nach der Migration in Feld- und Labordaten belegt werden; eine unbelegte Erfolgszahl wäre keine belastbare Fallstudie.
Optimierung 2: OnPush als Sofortmaßnahme
Falls eine vollständige Zoneless-Migration noch nicht möglich ist: ChangeDetectionStrategy.OnPush für alle Komponenten ist die schnellste Einzelmaßnahme.
- Ein
@Input()-Wert (per Referenz) sich ändert - Ein Event innerhalb der Komponente ausgelöst wird
- Explizit
markForCheck()aufgerufen wird - Ein gebundenes Observable einen neuen Wert emittiert
@Component({
selector: 'app-product-list',
templateUrl: './product-list.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ProductListComponent {}Faustregel: Jede Komponente ohne OnPush ist eine potenzielle INP-Bombe.

Optimierung 3: @defer für nicht-kritische Inhalte
@defer ist eines der am meisten unterschätzten Performance-Features seit Angular 17. Es ermöglicht es, Teile des Templates lazy zu laden — und hält damit den Haupt-Thread beim initialen Render frei.
<!-- Kommentarsektion erst laden wenn im Viewport sichtbar -->
@defer (on viewport) {
<app-comments [postId]="post.id" />
} @placeholder {
<div class="comments-skeleton">Kommentare werden geladen…</div>
}
<!-- Schwere Chart-Komponente erst nach Nutzer-Interaktion -->
@defer (on interaction) {
<app-performance-chart [data]="metrics" />
} @placeholder {
<button class="btn btn--secondary">Chart anzeigen</button>
}Optimierung 4: Schwere Berechnungen in Web Workers
Algorithmen, die viel CPU benötigen, blockieren den Haupt-Thread direkt. Das Ergebnis: Input Delay steigt, INP verschlechtert sich.
// product-filter.worker.ts
self.onmessage = ({ data }) => {
const { products, filters } = data;
const filtered = products.filter(p => matchesFilters(p, filters));
self.postMessage(filtered);
};
// component.ts
private readonly worker = new Worker(
new URL('./product-filter.worker', import.meta.url),
{ type: 'module' }
);
filterProducts(filters: Filters) {
this.worker.postMessage({ products: this.allProducts(), filters });
this.worker.onmessage = ({ data }) => this.filteredProducts.set(data);
}Die Filterlogik läuft jetzt parallel im Worker-Thread — der Haupt-Thread bleibt für Rendering frei.
Optimierung 5: Event Handler schlank halten
Ein häufiger INP-Killer ist zu viel Logik direkt im Event Handler. Alles was nach dem ersten Frame passiert, sollte verschoben werden.
// ❌ Problematisch
onClick() {
this.processLargeDataset(); // 200ms
this.updateMultipleSignals(); // 50ms
this.triggerAnimations(); // 30ms
// INP: ~280ms
}// ✅ Besser — Hauptthread sofort freigeben
onClick() {
// Sofortiges visuelles Feedback
this.isLoading.set(true);
// Schwere Arbeit nach dem Frame verschieben
setTimeout(() => {
this.processLargeDataset();
this.updateMultipleSignals();
this.isLoading.set(false);
}, 0);
}setTimeout(0) verschiebt Arbeit in eine neue Task und kann frühes visuelles Feedback ermöglichen. Es ist aber kein pauschaler INP-Fix: Lange Folge-Tasks müssen weiter aufgeteilt oder in einen Web Worker ausgelagert und anschließend erneut gemessen werden.

Zusammenfassung: INP-Checkliste für Angular
- OnPush für alle Komponenten — Aufwand: mittel, Wirkung: hoch
- Signals statt Observables für UI-State — Aufwand: mittel, Wirkung: hoch
- Zoneless Migration — Aufwand: hoch, Wirkung: sehr hoch
- @defer für nicht-kritische Blöcke — Aufwand: niedrig, Wirkung: mittel–hoch
- Web Workers für CPU-intensive Arbeit — Aufwand: hoch, Wirkung: situationsabhängig
- Event Handler entschlacken — Aufwand: niedrig, Wirkung: mittel
FAQ
@placeholder-Inhalt serverseitig gerendert. Die eigentliche Komponente lädt erst clientseitig, wenn der definierte Trigger ausgelöst wird.OnPush + Signals profitieren sofort von Zoneless. Komponenten ohne OnPush erfordern nach der Migration manuelle markForCheck()-Aufrufe.