Start · Sprachen · JavaScript · Referenz · TaskAttributionTiming

TaskAttributionTiming

Schnittstelle

Liefert Zuordnungsinformationen zu einer langen Aufgabe (Long Task), also in welchem Container (Fenster, <code>iframe</code>, <code>embed</code>, <code>object</code>) die blockierende Arbeit lief.

seit JavaScript Experimentell: Chromium 58+ (Chrome, Edge, Opera); Kategorie: webapi

Signatur

interface TaskAttributionTiming extends PerformanceEntry

Beschreibung

TaskAttributionTiming gehört zur Long Tasks API. Objekte dieser Schnittstelle erzeugt man nicht selbst. Man findet sie im Array attribution eines PerformanceLongTaskTiming-Eintrags. Den wiederum liefert ein PerformanceObserver mit dem Typ "longtask". Eine lange Aufgabe ist eine Aufgabe, die den Hauptthread mindestens 50 ms blockiert.

Die Schnittstelle beantwortet die Frage „Wo ist das passiert?“. Sie nennt den Container, in dem die Arbeit lief, samt Typ, Quelle (src), id und name. So lässt sich zum Beispiel herausfinden, ob ein Werbe- oder Tracking-iframe eines Drittanbieters oder die eigene Seite die Oberfläche ausbremst.

Da TaskAttributionTiming von PerformanceEntry erbt, hat es auch name, entryType (immer "taskattribution"), startTime und duration (beide immer 0). Mit toJSON() lässt sich ein Eintrag serialisieren und etwa an einen Monitoring-Endpunkt schicken.

Nützlich ist die Schnittstelle vor allem für das Real User Monitoring (RUM) und für die Fehlersuche bei schlechten Werten für Total Blocking Time oder Interaction to Next Paint. Zeilengenaue Angaben zum Skript liefert sie nicht. Dafür gibt es die neuere Long Animation Frames API.

Parameter

Name Typ Default Beschreibung
$containerType string Schreibgeschützte Eigenschaft. Typ des Containers: "window", "iframe", "embed" oder "object".
$containerSrc string Schreibgeschützte Eigenschaft. Wert des src-Attributs des Containers. Leerer String, wenn es keinen gibt.
$containerId string Schreibgeschützte Eigenschaft. Wert des id-Attributs des Containers.
$containerName string Schreibgeschützte Eigenschaft. Wert des name-Attributs des Containers.
$entryType string "taskattribution" Geerbt von PerformanceEntry. Immer "taskattribution".
$name string "unknown" Geerbt. Art der Zuordnung, derzeit praktisch immer "unknown".
$startTime / duration number 0 Geerbt. Bei dieser Schnittstelle immer 0.

Rückgabewert

Typ
TaskAttributionTiming
Beschreibung
Wird nicht per Konstruktor erzeugt. Instanzen stehen im Array PerformanceLongTaskTiming.attribution. Die Methode toJSON() gibt ein einfaches Objekt mit allen Eigenschaften zurück.

Beispiele

Lange Aufgaben beobachten und Container ausgeben

// Beobachtet lange Aufgaben (≥ 50 ms) und zeigt ihre Zuordnung
const observer = new PerformanceObserver((list) => {
  for (const task of list.getEntries()) {
    for (const attr of task.attribution) {
      // attr ist ein TaskAttributionTiming-Objekt
      console.log(
        `Long Task ${task.duration.toFixed(0)} ms →`,
        attr.containerType,
        attr.containerSrc || '(eigenes Fenster)'
      );
    }
  }
});

observer.observe({ type: 'longtask', buffered: true });
Long Task 124 ms → window (eigenes Fenster) Long Task 87 ms → iframe https://ads.example.com/banner.html

Blockierende Drittanbieter-iframes an ein Monitoring senden

const reportLongTasks = () => {
  if (!PerformanceObserver.supportedEntryTypes?.includes('longtask')) {
    console.info('Long Tasks API wird nicht unterstützt');
    return;
  }

  const observer = new PerformanceObserver((list) => {
    const payload = list.getEntries().flatMap((task) =>
      task.attribution
        .filter((attr) => attr.containerType !== 'window')
        .map((attr) => ({
          dauer: Math.round(task.duration),
          start: Math.round(task.startTime),
          ...attr.toJSON()
        }))
    );

    if (payload.length > 0) {
      navigator.sendBeacon('/rum/longtasks', JSON.stringify(payload));
    }
  });

  observer.observe({ type: 'longtask', buffered: true });
};

reportLongTasks();

Blockierzeit je Container zusammenzählen

const blockiertJeContainer = new Map();

new PerformanceObserver((list) => {
  for (const task of list.getEntries()) {
    const [attr] = task.attribution;
    const schluessel = attr
      ? `${attr.containerType}:${attr.containerId || attr.containerSrc || '-'}`
      : 'unbekannt';
    const bisher = blockiertJeContainer.get(schluessel) ?? 0;
    blockiertJeContainer.set(schluessel, bisher + task.duration - 50);
  }
}).observe({ type: 'longtask', buffered: true });

// Später, z. B. beim Verlassen der Seite
addEventListener('pagehide', () => {
  console.table(Object.fromEntries(blockiertJeContainer));
});
┌──────────────┬────────┐ │ window:- │ 312 │ │ iframe:promo │ 145 │ └──────────────┴────────┘

// Wichtig · Fallstricke

  • Experimentell und nur in Chromium: Chrome, Edge und Opera unterstützen die Schnittstelle, Firefox und Safari nicht. Prüfe das vorher mit PerformanceObserver.supportedEntryTypes.includes('longtask').
  • Grobe Zuordnung: Angegeben wird nur der Container, nicht das konkrete Skript, die Funktion oder die Zeile. name ist fast immer "unknown". Genauere Angaben liefert die Long Animation Frames API ("long-animation-frame").
  • Die Werte sind fest: startTime und duration sind immer 0. Die echten Zeiten stehen im übergeordneten PerformanceLongTaskTiming-Eintrag.
  • Datenschutz bei fremden Ursprüngen: Bei Containern von anderen Ursprüngen gibt der Browser teils weniger Details preis. Leere Werte bei containerSrc, containerId oder containerName sind normal.
  • Eine Instanz lässt sich nicht per new erzeugen. Ein direkter Konstruktor-Aufruf wirft einen TypeError.
  • Mit buffered: true erhält der Observer auch Einträge, die vor seiner Registrierung angefallen sind. Die Größe dieses Puffers ist aber begrenzt.