Signatur
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
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();
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');
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());
// 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. Liesdownloaded,uploaded,downloadTotal,uploadTotalundresultvon der Registrierung ab. downloadTotalist0, wenn beim Aufruf vonfetch()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 mitfailureReason"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,backgroundfetchfailundbackgroundfetchabort. - Das Ereignis kann sehr häufig feuern. Aufwendige DOM-Aktualisierungen solltest du drosseln, z. B. mit
requestAnimationFrame.