Start · Sprachen · JavaScript · Referenz · PerformanceScriptTiming.invokerType

PerformanceScriptTiming.invokerType

Eigenschaft

Schreibgeschützte Zeichenkette, die angibt, welche Art von Aufruf ein Skript in einem langen Animations-Frame gestartet hat, z. B. <code>"event-listener"</code> oder <code>"user-callback"</code>.

seit JavaScript Chrome/Edge 123+ (Long Animation Frames API), nich Kategorie: webapi

Signatur

PerformanceScriptTiming.invokerType

Beschreibung

Die Eigenschaft invokerType gehört zur Schnittstelle PerformanceScriptTiming aus der Long Animation Frames API (LoAF). Jeder Eintrag vom Typ long-animation-frame (PerformanceLongAnimationFrameTiming) enthält im Array scripts einzelne PerformanceScriptTiming-Objekte. invokerType zeigt an, auf welchem Weg das jeweilige Skript gestartet wurde.

Diese Werte sind möglich:

  • "classic-script": Ein klassisches Skript wird ausgewertet, z. B. <script src="…"> oder ein Inline-Skript.
  • "module-script": Ein ES-Modul wird ausgewertet (<script type="module">).
  • "event-listener": Ein Event-Listener läuft, etwa für click oder load, ob über addEventListener oder eine on…-Eigenschaft.
  • "user-callback": Ein Callback, der über eine Web-API eingeplant wurde, z. B. setTimeout, requestAnimationFrame oder requestIdleCallback.
  • "resolve-promise": Ein Handler für ein erfülltes Promise (then/await).
  • "reject-promise": Ein Handler für ein abgelehntes Promise (catch).

In der Praxis nutzt man invokerType zusammen mit invoker, sourceURL und duration. So findet man heraus, ob Ruckler durch Event-Handler, Timer, Promise-Ketten oder das erste Auswerten eines Skripts entstehen. Das hilft vor allem beim Verbessern der Kennzahl INP (Interaction to Next Paint) und beim Real User Monitoring (RUM).

Rückgabewert

Typ
string
Beschreibung
Einer der Werte "classic-script", "module-script", "event-listener", "user-callback", "resolve-promise" oder "reject-promise".

Beispiele

Aufruftypen in langen Animations-Frames protokollieren

const observer = new PerformanceObserver((list) => {
  for (const frame of list.getEntries()) {
    for (const script of frame.scripts) {
      console.log(
        `${script.invokerType} | ${script.invoker} | ${Math.round(script.duration)} ms`
      );
    }
  }
});

// buffered: true liefert auch Frames, die vor dem Registrieren aufgezeichnet wurden
observer.observe({ type: 'long-animation-frame', buffered: true });
event-listener | BUTTON#save.onclick | 182 ms user-callback | TimerHandler:setTimeout | 64 ms classic-script | https://example.com/app.js | 97 ms

Gesamte Skriptzeit pro Aufruftyp zusammenrechnen

const totals = new Map();

new PerformanceObserver((list) => {
  for (const frame of list.getEntries()) {
    for (const { invokerType, duration } of frame.scripts) {
      totals.set(invokerType, (totals.get(invokerType) ?? 0) + duration);
    }
  }
}).observe({ type: 'long-animation-frame', buffered: true });

// Wenn der Tab in den Hintergrund wechselt, Ergebnis ausgeben
document.addEventListener('visibilitychange', () => {
  if (document.visibilityState === 'hidden') {
    console.table(Object.fromEntries(
      [...totals].map(([typ, ms]) => [typ, Math.round(ms)])
    ));
  }
});
┌─────────────────┬────────┐ │ event-listener │ 540 │ │ resolve-promise │ 210 │ │ module-script │ 130 │ └─────────────────┴────────┘

Nur langsame Event-Handler per Beacon melden (INP-Analyse)

if (PerformanceObserver.supportedEntryTypes?.includes('long-animation-frame')) {
  new PerformanceObserver((list) => {
    const slowHandlers = list.getEntries()
      .flatMap((frame) => frame.scripts)
      .filter((s) => s.invokerType === 'event-listener' && s.duration > 50)
      .map((s) => ({
        invoker: s.invoker,
        source: s.sourceURL,
        fn: s.sourceFunctionName,
        duration: Math.round(s.duration)
      }));

    if (slowHandlers.length) {
      navigator.sendBeacon('/rum/loaf', JSON.stringify(slowHandlers));
    }
  }).observe({ type: 'long-animation-frame', buffered: true });
} else {
  console.log('Long Animation Frames API wird nicht unterstützt');
}

// Wichtig · Fallstricke

  • Browser-Unterstützung: Nur in Chromium-Browsern ab Version 123 (Chrome, Edge, Opera). Firefox und Safari unterstützen die API nicht. Vor der Nutzung mit PerformanceObserver.supportedEntryTypes.includes('long-animation-frame') prüfen.
  • Die Liste der Werte kann sich ändern, weil die Spezifikation noch nicht fertig ist. Unbekannte Werte deshalb nicht als Fehler behandeln. Am besten einen Standardzweig vorsehen, etwa default in einem switch.
  • Es erscheinen nur Skripte, die länger als etwa 5 ms laufen, und nur in Frames, die länger als 50 ms dauern. Kurze Aufrufe fehlen also in scripts.
  • Bei fremden Skripten ohne CORS-Freigabe (crossorigin) können Angaben wie sourceURL oder sourceFunctionName leer sein. invokerType selbst ist trotzdem vorhanden.
  • "user-callback" umfasst viele verschiedene APIs. Die genaue Quelle, z. B. setTimeout oder requestAnimationFrame, zeigt erst die Eigenschaft invoker.
  • Die Eigenschaft ist schreibgeschützt. Eine Zuweisung wird ohne Fehlermeldung ignoriert.