Signatur
Beschreibung
PerformanceLongTaskTiming gehört zur Long Tasks API. Der Browser erzeugt Einträge dieses Typs (entryType = "longtask"), sobald ein Task den Haupt-Thread ununterbrochen mindestens 50 ms belegt. Während dieser Zeit kann die Seite nicht auf Eingaben reagieren, nicht scrollen und nicht rendern. Das zeigt sich als Ruckeln oder spürbare Verzögerung.
Das Interface erbt von PerformanceEntry diese Eigenschaften: name (Herkunft des Tasks, z. B. "self", "same-origin-descendant", "cross-origin-ancestor", "multiple-contexts" oder "unknown"), entryType, startTime und duration. Eigen ist die Eigenschaft attribution: ein Array von TaskAttributionTiming-Objekten, das den verursachenden Browsing-Kontext beschreibt (z. B. einen iframe mit containerType, containerSrc, containerId und containerName). Hinzu kommt die Methode toJSON().
Einträge werden fast immer mit einem PerformanceObserver gesammelt. Mit buffered: true erhält man auch Tasks, die vor der Registrierung aufgetreten sind. Aus den Werten lassen sich Kennzahlen wie Total Blocking Time (TBT) oder eine Näherung für die Time to Interactive berechnen, typischerweise im Real-User-Monitoring (RUM).
Die Instanzen werden nur vom Browser erzeugt. Einen öffentlichen Konstruktor gibt es nicht.
Rückgabewert
PerformanceObserver (Typ "longtask") oder performance.getEntriesByType("longtask") bereitgestellt. Wichtige Eigenschaften sind startTime (DOMHighResTimeStamp), duration (ms, ≥ 50), name (string) und attribution (TaskAttributionTiming[]).Beispiele
Lange Tasks mit PerformanceObserver protokollieren
if (PerformanceObserver.supportedEntryTypes?.includes('longtask')) {
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
// entry ist ein PerformanceLongTaskTiming
console.log(
`Long Task: ${entry.duration.toFixed(0)} ms ab ${entry.startTime.toFixed(0)} ms (Quelle: ${entry.name})`
);
}
});
observer.observe({ type: 'longtask', buffered: true });
} else {
console.log('Long Tasks API wird nicht unterstützt');
}
// Künstlich einen langen Task erzeugen
const ende = performance.now() + 120;
while (performance.now() < ende) {}
Total Blocking Time (TBT) näherungsweise berechnen
let totalBlockingTime = 0;
const tbtObserver = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
// Nur der Anteil über 50 ms zählt als "blockierend"
totalBlockingTime += Math.max(0, entry.duration - 50);
}
});
tbtObserver.observe({ type: 'longtask', buffered: true });
// Beim Verlassen der Seite an das Monitoring senden
addEventListener('visibilitychange', () => {
if (document.visibilityState === 'hidden') {
navigator.sendBeacon('/rum', JSON.stringify({ tbt: Math.round(totalBlockingTime) }));
}
});
Verursacher über attribution ermitteln (z. B. Drittanbieter-iframe)
const obs = new PerformanceObserver((list) => {
for (const task of list.getEntries()) {
const [attr] = task.attribution;
console.table({
dauer: Math.round(task.duration),
herkunft: task.name,
containerTyp: attr?.containerType, // 'iframe', 'embed', 'object' oder 'window'
containerSrc: attr?.containerSrc,
containerId: attr?.containerId
});
console.log(JSON.stringify(task.toJSON()));
}
});
obs.observe({ type: 'longtask', buffered: true });
// Wichtig · Fallstricke
- Browser-Kompatibilität: Nur in Chromium-Browsern (Chrome, Edge, Opera) verfügbar. Firefox und Safari unterstützen
"longtask"nicht. Prüfe die Unterstützung vorher mitPerformanceObserver.supportedEntryTypes.includes('longtask'). - Grobe Zuordnung:
attributionnennt nur den Container (Frame/iframe), nicht das verursachende Skript oder die Funktion. Für Details auf Skriptebene gibt es in neueren Chromium-Versionen die Long Animation Frames API (PerformanceLongAnimationFrameTiming, Typ"long-animation-frame"). - Datenschutz: Bei fremden Origins werden Angaben wie
containerSrceingeschränkt, undnameist dann oft nur"cross-origin-…"oder"unknown". performance.getEntriesByType('longtask')liefert in Chrome meist ein leeres Array, weil Long Tasks nicht in die globale Performance-Timeline aufgenommen werden. Nutze stattdessenPerformanceObservermitbuffered: true.- Die 50-ms-Schwelle ist fest vorgegeben und lässt sich nicht einstellen. Kürzere, aber häufige Tasks werden nicht erfasst.
- Abhilfe bei langen Tasks: Arbeit aufteilen (z. B. mit
scheduler.yield(),setTimeoutoderrequestIdleCallback) oder in einen Web Worker auslagern.