Start · Sprachen · JavaScript · Referenz · EventCounts

EventCounts

Schnittstelle

Eine schreibgeschützte, Map-ähnliche Struktur, die über <code>performance.eventCounts</code> für jeden Ereignistyp angibt, wie oft er ausgelöst wurde.

seit JavaScript Chrome/Edge 85+, Firefox 89+; Safari: nicht unters Kategorie: webapi

Signatur

interface EventCounts

Beschreibung

Die Schnittstelle EventCounts gehört zur Event Timing API, einem Teil der Performance API. Eine Instanz bekommst du nie über einen Konstruktor, sondern immer über die Eigenschaft performance.eventCounts. Die Schlüssel sind Ereignistypen als Zeichenketten (etwa "click", "keydown" oder "pointerdown"), die Werte sind die Anzahl der Auslösungen seit dem Laden der Seite.

Das Objekt verhält sich wie eine schreibgeschützte Map. Es gibt also size, get(), has(), keys(), values(), entries(), forEach() und den Iterator [Symbol.iterator](). Methoden zum Ändern wie set(), delete() oder clear() fehlen. Die Zahlen führt der Browser selbst mit.

Gezählt werden nur Ereignistypen, die auch die Event Timing API erfasst. Das sind vor allem Nutzerinteraktionen wie Maus-, Zeiger-, Tastatur-, Touch-, Drag-, Fokus- und Eingabe-Ereignisse. Solche Zähler sind nützlich für Real User Monitoring (RUM): Du kannst damit Kennzahlen wie Interaction to Next Paint (INP) ins Verhältnis setzen, etwa „langsame Interaktionen pro 100 Klicks“, oder einfach messen, wie viel Nutzer mit einer Seite interagieren.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Parameter von get(type) und has(type): der Ereignistyp, z. B. "click". Groß- und Kleinschreibung zählt.
$callbackFn Pflicht (value: number, key: string, map: EventCounts) => void Parameter von forEach(): Funktion, die für jedes Schlüssel-Wert-Paar aufgerufen wird.
$thisArg any undefined Optionaler Wert für this innerhalb von callbackFn bei forEach().

Rückgabewert

Typ
EventCounts
Beschreibung
performance.eventCounts gibt das EventCounts-Objekt der Seite zurück. get() gibt eine number zurück (bei unbekannten Typen undefined), has() ein boolean, size die Anzahl der erfassten Ereignistypen.

Beispiele

Instanz holen und einzelne Zähler abfragen

// EventCounts erhältst du nur über performance.eventCounts
if ('eventCounts' in performance) {
  const counts = performance.eventCounts;
  console.log(counts instanceof EventCounts); // true
  console.log('Klicks:', counts.get('click'));
  console.log('keydown bekannt?', counts.has('keydown'));
  console.log('Erfasste Typen:', counts.size);
} else {
  console.log('Event Timing API wird nicht unterstützt');
}
true Klicks: 3 keydown bekannt? true Erfasste Typen: 36

Alle Ereignistypen mit mindestens einer Auslösung auflisten

const used = [...performance.eventCounts.entries()]
  .filter(([, count]) => count > 0)
  .sort((a, b) => b[1] - a[1]);

for (const [type, count] of used) {
  console.log(`${type}: ${count}`);
}
pointermove: 412 mousemove: 398 pointerdown: 5 click: 5 keydown: 2

RUM: Interaktionen beim Verlassen der Seite senden

const sendEventStats = () => {
  if (!('eventCounts' in performance)) return;
  const stats = Object.fromEntries(performance.eventCounts);
  const payload = JSON.stringify({
    url: location.pathname,
    clicks: stats.click ?? 0,
    keydowns: stats.keydown ?? 0,
    pointerdowns: stats.pointerdown ?? 0
  });
  navigator.sendBeacon('/analytics/events', payload);
};

document.addEventListener('visibilitychange', () => {
  if (document.visibilityState === 'hidden') sendEventStats();
});

Anteil langsamer Interaktionen berechnen

let slowClicks = 0;

new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if (entry.name === 'click' && entry.duration > 200) slowClicks++;
  }
}).observe({ type: 'event', durationThreshold: 104, buffered: true });

setTimeout(() => {
  const total = performance.eventCounts.get('click') ?? 0;
  const ratio = total ? ((slowClicks / total) * 100).toFixed(1) : '0.0';
  console.log(`Langsame Klicks: ${slowClicks}/${total} (${ratio} %)`);
}, 10000);
Langsame Klicks: 1/12 (8.3 %)

// Wichtig · Fallstricke

  • Browser-Kompatibilität: Unterstützt ab Chromium 85 (Chrome, Edge, Opera) und Firefox 89. Safari unterstützt die API nicht. Prüfe deshalb immer vorher mit 'eventCounts' in performance.
  • Kein Konstruktor: new EventCounts() wirft einen TypeError. Nutze ausschließlich performance.eventCounts.
  • Schreibgeschützt: set(), delete() und clear() gibt es nicht. Die Zähler lassen sich nicht zurücksetzen. Wenn du Zeiträume auswerten willst, speichere dir einen Schnappschuss (new Map(performance.eventCounts)) und bilde die Differenz.
  • Nicht jeder Typ wird erfasst: Nur die Ereignistypen der Event Timing API werden gezählt. Für andere Typen wie scroll oder eigene Ereignisse (CustomEvent) liefert get() den Wert undefined. Erfasste, aber noch nie ausgelöste Typen stehen meist schon mit 0 in der Liste, deshalb ist size nicht gleich „Anzahl benutzter Typen“.
  • Nur vertrauenswürdige Ereignisse: Per dispatchEvent() ausgelöste, also synthetische Ereignisse (isTrusted === false) werden nicht gezählt.
  • Leistung: Das Abfragen kostet fast nichts, weil der Browser ohnehin zählt. Zusätzliche Event-Listener nur fürs Zählen brauchst du nicht.