Signatur
Beschreibung
IdleDeadline ist der Datentyp des einzigen Parameters, den der Browser an einen mit window.requestIdleCallback() registrierten Callback übergibt. Selbst erzeugt man solche Objekte nie – sie werden ausschließlich vom Browser bereitgestellt, wenn der Haupt-Thread gerade nichts zu tun hat (etwa zwischen zwei Frames oder wenn keine Benutzereingaben anstehen).
Das Interface hat zwei Mitglieder:
timeRemaining()– Methode, die alsDOMHighResTimeStamp(Millisekunden, Gleitkommazahl) zurückgibt, wie viel Zeit in der aktuellen Leerlaufphase schätzungsweise noch verbleibt. Der Wert liegt höchstens bei 50 ms und fällt auf0, sobald die Phase vorbei ist.didTimeout– schreibgeschützte boolesche Eigenschaft. Sie isttrue, wenn der Callback nicht wegen echter Leerlaufzeit, sondern deshalb ausgeführt wird, weil das beim Registrieren angegebenetimeoutabgelaufen ist.
Typischerweise nutzt man IdleDeadline, um niedrig priorisierte Arbeit – Analytics-Daten versenden, Vorab-Berechnungen, Cache-Aufwärmen, Indexierung – in kleine Häppchen zu zerlegen. In einer Schleife wird so lange abgearbeitet, wie timeRemaining() > 0 gilt (oder didTimeout gesetzt ist); verbleibende Aufgaben werden per erneutem requestIdleCallback() auf die nächste Leerlaufphase verschoben. So bleibt die Seite flüssig und reaktionsfähig.
Rückgabewert
timeRemaining(): number und didTimeout: boolean.Beispiele
Grundlagen: IdleDeadline im Callback auslesen
requestIdleCallback((deadline) => {
console.log(deadline instanceof IdleDeadline);
console.log('Restzeit (ms):', deadline.timeRemaining().toFixed(2));
console.log('Timeout erreicht?', deadline.didTimeout);
});
Aufgaben-Warteschlange in Leerlaufphasen abarbeiten
const tasks = Array.from({ length: 1000 }, (_, i) => () => Math.sqrt(i) * Math.random());
let processed = 0;
const processTasks = (deadline) => {
// Arbeiten, solange Zeit bleibt oder das Timeout erzwungen wurde
while ((deadline.timeRemaining() > 1 || deadline.didTimeout) && tasks.length > 0) {
const task = tasks.shift();
task();
processed++;
}
if (tasks.length > 0) {
// Rest in der nächsten Leerlaufphase erledigen
requestIdleCallback(processTasks, { timeout: 2000 });
} else {
console.log(`Fertig: ${processed} Aufgaben verarbeitet`);
}
};
requestIdleCallback(processTasks, { timeout: 2000 });
Analytics-Events gebündelt im Leerlauf senden
const queue = [];
let scheduled = false;
const track = (event) => {
queue.push({ ...event, ts: Date.now() });
if (!scheduled) {
scheduled = true;
requestIdleCallback(flush, { timeout: 5000 });
}
};
const flush = (deadline) => {
const batch = [];
while (queue.length && (deadline.timeRemaining() > 0 || deadline.didTimeout)) {
batch.push(queue.shift());
}
if (batch.length) {
navigator.sendBeacon('/analytics', JSON.stringify(batch));
console.log(`${batch.length} Events gesendet${deadline.didTimeout ? ' (per Timeout)' : ''}`);
}
scheduled = queue.length > 0;
if (scheduled) requestIdleCallback(flush, { timeout: 5000 });
};
track({ type: 'pageview', path: location.pathname });
track({ type: 'click', target: 'cta-button' });
Fallback für Browser ohne requestIdleCallback (z. B. Safari)
const ric = window.requestIdleCallback ?? ((cb) => {
const start = performance.now();
// Nachgebautes IdleDeadline-ähnliches Objekt
return setTimeout(() => cb({
didTimeout: false,
timeRemaining: () => Math.max(0, 50 - (performance.now() - start))
}), 1);
});
ric((deadline) => {
console.log('Restzeit:', Math.round(deadline.timeRemaining()), 'ms');
});
// Wichtig · Fallstricke
- Browser-Unterstützung: Chrome/Edge und Firefox unterstützen
IdleDeadline; Safari bietetrequestIdleCallbackstandardmäßig nicht an. Immer per Feature-Erkennung ('requestIdleCallback' in window) prüfen und einen Fallback mitsetTimeoutbereithalten. timeRemaining()ist dynamisch: Der Wert sinkt während der Ausführung. Ihn nur einmal am Anfang zu lesen und dann lange zu arbeiten, untergräbt den Zweck. Vor jeder Teilaufgabe erneut abfragen.- Maximal 50 ms: Auch bei völlig untätigem Browser liefert
timeRemaining()nie mehr als 50 ms, damit Benutzereingaben schnell bedient werden können. didTimeout === trueheißt nicht „Zeit vorhanden“: In diesem Fall gibttimeRemaining()meist0zurück. Nur das Nötigste erledigen, sonst entstehen Ruckler.- Keine DOM-Änderungen im Idle-Callback: Layout-Änderungen können die Frame-Planung stören und erzwungene Reflows auslösen. DOM-Arbeiten lieber per
requestAnimationFrame()einplanen. - Promise-Auflösungen im Callback laufen sofort nach seinem Ende und können die Leerlaufphase überschreiten.
- In Hintergrund-Tabs werden Idle-Callbacks stark gedrosselt oder gar nicht ausgeführt – ohne
timeoutkann Arbeit sehr lange liegen bleiben.