Signatur
Beschreibung
Das sync-Ereignis gehört zur Background Synchronization API. Eine Seite oder ein Worker meldet über registration.sync.register(tag) eine Synchronisation an. Der Browser löst das Ereignis im Service Worker aus, sobald eine Netzwerkverbindung besteht. Ist das Gerät bei der Anmeldung schon online, feuert das Ereignis fast sofort, sonst erst, wenn die Verbindung zurückkommt. Das funktioniert auch dann, wenn der Nutzer die Seite inzwischen geschlossen hat.
Der Handler bekommt ein SyncEvent-Objekt (erweitert ExtendableEvent). Es hat die Eigenschaften tag (der bei der Anmeldung vergebene Name) und lastChance. lastChance ist true, wenn der Browser nach diesem Versuch keinen weiteren mehr startet. Mit event.waitUntil(promise) teilen Sie dem Browser mit, wie lange die Arbeit dauert. Wird das Promise abgelehnt, plant der Browser automatisch einen neuen Versuch mit wachsendem Abstand ein (exponentieller Backoff).
Typische Einsätze sind Offline-First-Anwendungen. Formulardaten, Chat-Nachrichten oder Analysedaten werden offline zuerst in IndexedDB gespeichert und im sync-Handler gesammelt an den Server geschickt. Das Ereignis lässt sich per addEventListener("sync", …) oder über die Eigenschaft self.onsync abonnieren.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignisname "sync". |
|
| $handler Pflicht | (event: SyncEvent) => void | Callback, der ein SyncEvent erhält. Wichtige Eigenschaften: event.tag (string), event.lastChance (boolean) und die Methode event.waitUntil(promise). |
|
| $options | boolean | AddEventListenerOptions | false | Optionale Listener-Optionen wie once oder signal. |
Rückgabewert
addEventListener gibt nichts zurück. Ob die Synchronisation geklappt hat, bestimmt das Promise, das an event.waitUntil() übergeben wird.Beispiele
Synchronisation auf der Seite anmelden
// main.js – im Seitenkontext
const sendeSpaeter = async () => {
const registration = await navigator.serviceWorker.ready;
if ('sync' in registration) {
await registration.sync.register('ausgang-senden');
console.log('Sync registriert');
} else {
// Ausweichlösung: direkt senden
await fetch('/api/nachrichten', { method: 'POST' });
}
};
sendeSpaeter();
sync-Ereignis im Service Worker behandeln
// sw.js
const sendeAusgang = async () => {
const cache = await caches.open('ausgang');
const anfragen = await cache.keys();
for (const req of anfragen) {
const res = await fetch(req.clone());
if (!res.ok) throw new Error(`HTTP ${res.status}`); // löst einen neuen Versuch aus
await cache.delete(req);
}
console.log(`${anfragen.length} Einträge synchronisiert`);
};
self.addEventListener('sync', (event) => {
if (event.tag === 'ausgang-senden') {
event.waitUntil(sendeAusgang());
}
});
onsync-Eigenschaft und lastChance auswerten
// sw.js
self.onsync = (event) => {
event.waitUntil((async () => {
try {
await fetch('/api/statistik', { method: 'POST', body: '{}' });
} catch (err) {
if (event.lastChance) {
// Letzter Versuch – Nutzer informieren
await self.registration.showNotification('Synchronisation fehlgeschlagen');
return;
}
throw err; // Browser versucht es später erneut
}
})());
};
// Wichtig · Fallstricke
- Browser-Unterstützung: Nur Chromium-basierte Browser (Chrome, Edge, Opera, Samsung Internet). Firefox und Safari unterstützen die API nicht. Prüfen Sie das deshalb immer mit
'sync' in registrationund halten Sie eine Ausweichlösung bereit, etwa sofort senden oder beim nächsten Seitenaufruf nachholen. - Nur in sicheren Kontexten: Die API funktioniert nur über HTTPS (oder
localhost) und nur mit einem aktiven Service Worker. - Ohne
event.waitUntil()kann der Browser den Worker beenden, bevor die asynchrone Arbeit fertig ist. Außerdem gibt es dann keine automatischen Wiederholungen. - Browser begrenzen die Laufzeit eines Versuchs (in Chrome einige Minuten) und die Zahl der Wiederholungen (in Chrome standardmäßig drei). Beim letzten Versuch ist
lastChancegleichtrue. - Mehrfache Anmeldungen mit demselben
tagwerden zusammengefasst, solange die Synchronisation noch aussteht. Das eignet sich zum Entprellen. - Das Ereignis bekommt keine Nutzdaten. Speichern Sie die zu sendenden Daten vorher in IndexedDB oder in der Cache API.
- Für regelmäßige Aktualisierungen gibt es die eigene Periodic Background Sync API mit dem Ereignis
periodicsync.