Start · Sprachen · JavaScript · Referenz · IdleDeadline.timeRemaining()

IdleDeadline.timeRemaining()

Methode

Gibt die geschätzte Zeit in Millisekunden zurück, die im aktuellen Leerlaufzeitraum noch für Hintergrundarbeit zur Verfügung steht.

seit JavaScript Chrome 47+, Firefox 55+, Edge 79+, Safari: nicht s Kategorie: webapi

Signatur

IdleDeadline.prototype.timeRemaining()

Beschreibung

timeRemaining() wird auf dem IdleDeadline-Objekt aufgerufen, das der Browser einem mit requestIdleCallback() registrierten Callback übergibt. Die Methode gibt einen DOMHighResTimeStamp zurück. Das ist eine Gleitkommazahl in Millisekunden und gibt an, wie viel Zeit bis zum Ende des aktuellen Leerlaufzeitraums noch übrig ist.

Gedacht ist die Methode für kooperatives Scheduling: Man teilt unwichtige Arbeit in kleine Einheiten auf (Analytics senden, Daten vorberechnen, Caches aufwärmen, Listen vorrendern) und arbeitet diese in einer Schleife ab, solange timeRemaining() einen ausreichend großen Wert liefert. Ist die Zeit aufgebraucht, gibt man die Kontrolle an den Browser zurück und plant mit einem erneuten requestIdleCallback() den nächsten Durchlauf ein.

Der Wert ist höchstens 50 ms, damit der Browser bei einer Nutzereingabe innerhalb der Wahrnehmungsgrenze reagieren kann. Ist der Leerlaufzeitraum vorbei, oder wurde der Callback wegen eines abgelaufenen timeout aufgerufen, gibt die Methode 0 zurück. In diesem Fall zeigt deadline.didTimeout an, ob ein Timeout der Grund war.

Rückgabewert

Typ
number (DOMHighResTimeStamp)
Beschreibung
Geschätzte verbleibende Leerlaufzeit in Millisekunden als Gleitkommazahl zwischen 0 und 50. Der Wert ist 0, wenn der Leerlaufzeitraum abgelaufen ist.

Beispiele

Aufgaben-Warteschlange in Leerlaufzeiten abarbeiten

const tasks = Array.from({ length: 1000 }, (_, i) => () => Math.sqrt(i) * Math.random());
let processed = 0;

const work = (deadline) => {
  // Weiterarbeiten, solange Zeit übrig ist oder ein Timeout erzwungen wurde
  while ((deadline.timeRemaining() > 1 || deadline.didTimeout) && tasks.length > 0) {
    tasks.shift()();
    processed++;
  }

  if (tasks.length > 0) {
    requestIdleCallback(work, { timeout: 2000 });
  } else {
    console.log(`Fertig: ${processed} Aufgaben verarbeitet`);
  }
};

requestIdleCallback(work, { timeout: 2000 });
Fertig: 1000 Aufgaben verarbeitet

Verfügbare Leerlaufzeit protokollieren

requestIdleCallback((deadline) => {
  const ms = deadline.timeRemaining();
  console.log(`Verbleibend: ${ms.toFixed(2)} ms, Timeout: ${deadline.didTimeout}`);
});
Verbleibend: 49.80 ms, Timeout: false

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() > 2 || deadline.didTimeout)) {
    batch.push(queue.shift());
  }
  if (batch.length) {
    navigator.sendBeacon('/analytics', JSON.stringify(batch));
  }
  scheduled = queue.length > 0;
  if (scheduled) requestIdleCallback(flush, { timeout: 5000 });
};

track('page_view');
track('button_click');

// Wichtig · Fallstricke

  • Keine DOM-Änderungen im Idle-Callback: Layout-Änderungen können Reflows auslösen, die länger dauern als die verbleibende Zeit. DOM-Updates sollte man stattdessen mit requestAnimationFrame() einplanen.
  • Den Wert bei jedem Schleifendurchlauf neu abfragen. Er ändert sich laufend und sollte nicht zwischengespeichert werden.
  • Eine einzelne Arbeitseinheit sollte deutlich kürzer sein als die verbleibende Zeit. Sonst überschreitet man die Deadline trotz Prüfung.
  • Wurde der Callback wegen eines timeout aufgerufen, liefert timeRemaining() 0. Deshalb zusätzlich didTimeout prüfen, sonst wird nie gearbeitet.
  • Der Rückgabewert kann aus Datenschutzgründen (Schutz vor Timing-Angriffen) mit geringerer Genauigkeit geliefert werden.
  • Kompatibilität: Safari unterstützt requestIdleCallback() nicht standardmäßig. Mit einer Feature-Erkennung ('requestIdleCallback' in window) prüfen und als Ersatz z. B. setTimeout mit einem nachgebildeten Deadline-Objekt verwenden.