Start · Sprachen · JavaScript · Referenz · BackgroundFetchRegistration: progress

BackgroundFetchRegistration: progress

Ereignis

Wird an einer <code>BackgroundFetchRegistration</code> ausgelöst, wenn sich der Fortschritt des zugehörigen Hintergrundabrufs ändert (z. B. <code>downloaded</code>, <code>uploaded</code>, <code>result</code>).

seit JavaScript Experimentell: nur Chromium-basierte Browser (Chro Kategorie: webapi

Signatur

registration.addEventListener("progress", handler)

Beschreibung

Das progress-Ereignis gehört zur Background Fetch API. Es wird an einem BackgroundFetchRegistration-Objekt ausgelöst, sobald der Browser für den zugehörigen Hintergrundabruf Fortschritt meldet: Es kamen Bytes hinzu (downloaded), es wurden Bytes gesendet (uploaded), oder der Abruf hat einen Endzustand erreicht (result und ggf. failureReason ändern sich).

Das Ereignis ist ein einfaches Event ohne zusätzliche Eigenschaften. Die aktuellen Werte liest man direkt vom Registrierungsobjekt ab, also event.currentTarget bzw. über die Variable der Registrierung. Zusammen mit downloadTotal lässt sich daraus ein Fortschrittsbalken in Prozent berechnen.

Man registriert den Handler entweder per registration.addEventListener("progress", handler) oder über die Eigenschaft registration.onprogress = handler. Das funktioniert sowohl im Fensterkontext (Registrierung aus serviceWorkerRegistration.backgroundFetch.fetch() oder .get()) als auch im Service Worker selbst.

Typische Einsatzfälle sind große Downloads wie Filme, Podcasts oder Offline-Pakete, die weiterlaufen sollen, auch wenn der Nutzer die Seite schließt. Solange die Seite geöffnet ist, zeigt man mit progress den Fortschritt in der eigenen Oberfläche an.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignisname, hier immer "progress".
$handler Pflicht (event: Event) => void Callback, der bei jeder Fortschrittsänderung aufgerufen wird. event.currentTarget ist die BackgroundFetchRegistration.
$options boolean|AddEventListenerOptions false Übliche Listener-Optionen wie once oder signal.

Rückgabewert

Typ
void
Beschreibung
addEventListener gibt nichts zurück. Das Ereignis selbst ist ein generisches Event, die Fortschrittswerte liest man vom Registrierungsobjekt ab.

Beispiele

Fortschrittsbalken beim Starten eines Hintergrundabrufs

const startDownload = async () => {
  const swReg = await navigator.serviceWorker.ready;
  if (!('backgroundFetch' in swReg)) {
    console.log('Background Fetch nicht unterstützt');
    return;
  }

  const bgFetch = await swReg.backgroundFetch.fetch(
    'film-42',
    ['/media/film-42.mp4'],
    { title: 'Film 42 wird geladen', downloadTotal: 250 * 1024 * 1024 }
  );

  const bar = document.querySelector('progress#dl');

  bgFetch.addEventListener('progress', () => {
    if (!bgFetch.downloadTotal) return;
    const percent = Math.round((bgFetch.downloaded / bgFetch.downloadTotal) * 100);
    bar.value = percent;
    console.log(`Fortschritt: ${percent} %`);
  });
};

startDownload();
Fortschritt: 3 % Fortschritt: 17 % …

Laufenden Abruf per onprogress wieder aufnehmen und Ende erkennen

const watchExisting = async (id) => {
  const swReg = await navigator.serviceWorker.ready;
  const bgFetch = await swReg.backgroundFetch.get(id);
  if (!bgFetch) return;

  bgFetch.onprogress = (event) => {
    const reg = event.currentTarget;
    if (reg.result === '') {
      console.log(`${reg.downloaded} von ${reg.downloadTotal} Bytes`);
      return;
    }
    // Endzustand erreicht
    console.log('Ergebnis:', reg.result, reg.failureReason || '(kein Fehler)');
    reg.onprogress = null; // Handler entfernen
  };
};

watchExisting('film-42');
104857600 von 262144000 Bytes Ergebnis: success (kein Fehler)

Listener mit AbortController entfernen

const controller = new AbortController();

const track = async () => {
  const swReg = await navigator.serviceWorker.ready;
  const bgFetch = await swReg.backgroundFetch.get('podcast-7');
  if (!bgFetch) return;

  const onProgress = () => console.log('Geladen:', bgFetch.downloaded);
  bgFetch.addEventListener('progress', onProgress, { signal: controller.signal });

  // Alternativ: bgFetch.removeEventListener('progress', onProgress);
};

track();
// Beim Verlassen der Ansicht:
document.querySelector('#close').addEventListener('click', () => controller.abort());
Geladen: 524288

// Wichtig · Fallstricke

  • Kompatibilität: Die Background Fetch API ist experimentell und nur in Chromium-Browsern verfügbar (Chrome, Edge, Opera, Samsung Internet). Firefox und Safari unterstützen sie nicht. Prüfe deshalb immer mit 'backgroundFetch' in registration, ob sie vorhanden ist.
  • Die API gibt es nur in sicheren Kontexten (HTTPS) und nur mit einem aktiven Service Worker.
  • Das Ereignis enthält keine eigenen Fortschrittsdaten wie ProgressEvent.loaded. Lies downloaded, uploaded, downloadTotal, uploadTotal und result von der Registrierung ab.
  • downloadTotal ist 0, wenn beim Aufruf von fetch() kein Wert angegeben wurde. Prüfe das vor der Prozentberechnung, sonst teilst du durch null. Übersteigt der Download den angegebenen Wert, bricht der Browser den Abruf mit failureReason "download-total-exceeded" ab.
  • Das Ereignis kommt nur an, solange die Seite oder der Service Worker läuft. Den Abschluss im Hintergrund behandelst du im Service Worker mit den Ereignissen backgroundfetchsuccess, backgroundfetchfail und backgroundfetchabort.
  • Das Ereignis kann sehr häufig feuern. Aufwendige DOM-Aktualisierungen solltest du drosseln, z. B. mit requestAnimationFrame.