Signatur
Beschreibung
performance.interactionCount gehört zur Event Timing API. Die Eigenschaft liefert eine Zahl, die bei jeder abgeschlossenen, eigenständigen Benutzerinteraktion um eins steigt. Als Interaktion zählen Zeigerinteraktionen (Klick oder Tippen: pointerdown, pointerup, click) und Tastaturinteraktionen (keydown, keyup). Mehrere Einzel-Events, die zu derselben Geste gehören, erhalten dieselbe interactionId und werden nur einmal gezählt. Scrollen, Hovern und Zoomen gelten nicht als Interaktion.
Wichtig ist die Eigenschaft vor allem für die Messung von Interaction to Next Paint (INP), einer der Core Web Vitals. INP soll nicht die langsamste Interaktion abbilden, sondern ungefähr das 98. Perzentil. Dafür muss man wissen, wie viele Interaktionen es insgesamt gab. Vorgehen: Auf je 50 Interaktionen wird ein Ausreißer ignoriert. PerformanceEventTiming-Einträge, die ein PerformanceObserver liefert, decken dafür nicht alles ab, weil nur Events über einer Mindestdauer (durationThreshold, standardmäßig 104 ms, mindestens 16 ms) gemeldet werden. interactionCount zählt dagegen alle Interaktionen, auch die schnellen.
Der Wert ist eine nicht-negative ganze Zahl und startet beim Laden der Seite mit 0. Nutzen kann man ihn auch als einfachen Engagement-Indikator, zum Beispiel um beim Verlassen der Seite mitzuschicken, ob und wie viel der Nutzer interagiert hat.
Rückgabewert
interactionId) seit dem Laden der Seite. Anfangswert ist 0.Beispiele
Feature-Erkennung und Auslesen
if ('interactionCount' in performance) {
console.log(`Bisherige Interaktionen: ${performance.interactionCount}`);
} else {
console.log('performance.interactionCount wird nicht unterstützt');
}
INP näherungsweise berechnen (98. Perzentil)
// Längste Dauer je Interaktion merken
const interactions = new Map();
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (!entry.interactionId) continue; // kein Teil einer Interaktion
const prev = interactions.get(entry.interactionId) ?? 0;
interactions.set(entry.interactionId, Math.max(prev, entry.duration));
}
});
observer.observe({ type: 'event', durationThreshold: 16, buffered: true });
const estimateINP = () => {
const durations = [...interactions.values()].sort((a, b) => b - a);
if (durations.length === 0) return 0;
// Pro 50 Interaktionen einen Ausreißer überspringen
const count = performance.interactionCount ?? durations.length;
const index = Math.min(durations.length - 1, Math.floor(count / 50));
return durations[index];
};
document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'hidden') {
console.log(`INP ≈ ${Math.round(estimateINP())} ms`);
}
});
Engagement beim Verlassen der Seite melden
addEventListener('pagehide', () => {
const payload = JSON.stringify({
url: location.pathname,
interactions: performance.interactionCount ?? null,
timeOnPage: Math.round(performance.now())
});
// sendBeacon funktioniert auch beim Entladen zuverlässig
navigator.sendBeacon('/analytics/engagement', payload);
});
// Wichtig · Fallstricke
- Browser-Unterstützung: Die Eigenschaft ist nicht Baseline. Chromium-Browser und neuere Firefox-Versionen unterstützen sie, Safari bisher nicht. Prüfe deshalb immer mit
'interactionCount' in performanceund sieh einen Ersatzweg vor, etwa die Anzahl der beobachteteninteractionId-Werte. Diese ist allerdings zu niedrig, weil kurze Events unter demdurationThresholdfehlen. - Zählweise: Gezählt werden Interaktionen, keine einzelnen Events. Ein Klick löst
pointerdown,pointerupundclickaus, zählt aber nur einmal. Scrollen, Hovern und reinemousemove-Bewegungen zählen gar nicht. - Nur lesbar: Eine Zuweisung wie
performance.interactionCount = 0wird stillschweigend ignoriert, im Strict Mode gibt es keinen Fehler, da nur ein Getter existiert. Ein Zurücksetzen ist nicht möglich. Bei Single-Page-Apps musst du Differenzen je Route selbst berechnen, z. B. den Wert beim Routenwechsel speichern. - bfcache: Wird eine Seite aus dem Back/Forward-Cache wiederhergestellt, läuft der Zähler weiter und startet nicht neu. Für Messungen pro Seitenbesuch im
pageshow-Event (event.persisted) einen Startwert merken. - Für produktive INP-Messung ist die Bibliothek
web-vitalsempfehlenswert. Sie behandelt diese Randfälle und fehlende Unterstützung bereits.