Der moderne Ansatz
Mit der regelmäßigen Hintergrundsynchronisierung können Sie aktuelle Inhalte anzeigen, wenn eine progressive Web-App oder eine Seite mit Service Worker-Unterstützung gestartet wird. Dazu werden Daten im Hintergrund heruntergeladen, wenn die App oder Seite nicht verwendet wird.
Periodic Background Sync API verwenden
Nachdem der Service Worker installiert wurde, fragen Sie mit der
Permissions API nach
periodic-background-sync. Sie können dies entweder über ein Fenster oder einen Service Worker-Kontext tun.
const status = await navigator.permissions.query({
name: 'periodic-background-sync',
});
if (status.state === 'granted') {
// Periodic background sync can be used.
} else {
// Periodic background sync cannot be used.
}
Für die Registrierung einer regelmäßigen Synchronisierung sind ein Tag und ein Mindestsynchronisierungsintervall (minInterval) erforderlich. Mit dem Tag wird die registrierte Synchronisierung identifiziert, sodass mehrere Synchronisierungen registriert werden können. Im
folgenden Beispiel ist der Tag-Name 'content-sync' und das minInterval ein Tag.
navigator.serviceWorker.ready.then(async registration => {
try {
await registration.periodicSync.register('get-cats', { minInterval: 24 * 60 * 60 * 1000 });
console.log('Periodic background sync registered.');
} catch (err) {
console.error(err.name, err.message);
}
});
Rufen Sie periodicSync.getTags() auf, um ein Array von Registrierungs-Tags abzurufen. Im folgenden Beispiel werden Tag-Namen verwendet, um zu bestätigen, dass die Cache-Aktualisierung aktiv ist, damit sie nicht noch einmal aktualisiert wird.
const registration = await navigator.serviceWorker.ready;
if ('periodicSync' in registration) {
const tags = await registration.periodicSync.getTags();
// Only update content if sync isn't set up.
if (!tags.includes('content-sync')) {
updateContentOnPageLoad();
}
} else {
// If periodic background sync isn't supported, always update.
updateContentOnPageLoad();
}
Wenn Sie auf ein regelmäßiges Hintergrundsynchronisierungsereignis reagieren möchten, fügen Sie Ihrem Service Worker einen periodicsync-Event-Handler hinzu. Das an ihn übergebene Ereignisobjekt enthält einen Tag-Parameter, der mit dem bei der Registrierung verwendeten Wert übereinstimmt. Wenn beispielsweise eine regelmäßige Hintergrundsynchronisierung mit dem Namen
'content-sync', dann ist event.tag gleich 'content-sync'.
self.addEventListener('periodicsync', (event) => {
if (event.tag === 'content-sync') {
event.waitUntil(syncContent());
}
});
Browserkompatibilität
Der klassische Ansatz
Anstatt Daten im Hintergrund zu aktualisieren, damit sie verfügbar sind, wenn der Nutzer die App lädt, werden die Daten beim klassischen Ansatz einfach beim Laden aktualisiert.
Weitere Informationen
- Richer offline experiences with the Periodic Background Sync API
- Web Periodic Background Synchronization API
Demo
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link
rel="icon"
href=""
/>
<link rel="manifest" href="./manifest.json" />
<title>How to periodically synchronize data in the background</title>
<link rel="stylesheet" href="/style.css" />
<!-- TODO: Devsite - Removed inline handlers -->
<!-- <script src="/script.js" defer></script> -->
</head>
<body>
<h1>How to periodically synchronize data in the background</h1>
<p class="available">Periodic background sync can be used. Install the app first.</p>
<p class="not-available">Periodic background sync cannot be used.</p>
<h2>Last updated</h2>
<p class="last-updated">Never</p>
<h2>Registered tags</h2>
<ul>
<li>None yet.</li>
</ul>
</body>
</html>CSS
html {
box-sizing: border-box;
font-family: system-ui, sans-serif;
color-scheme: dark light;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
body {
margin: 1rem;
}
JS
const available = document.querySelector('.available');
const notAvailable = document.querySelector('.not-available');
const ul = document.querySelector('ul');
const lastUpdated = document.querySelector('.last-updated');
const updateContent = async () => {
const data = await fetch(
'https://worldtimeapi.org/api/timezone/Europe/London.json'
).then((response) => response.json());
return new Date(data.unixtime * 1000);
};
const registerPeriodicBackgroundSync = async (registration) => {
const status = await navigator.permissions.query({
name: 'periodic-background-sync',
});
if (status.state === 'granted' && 'periodicSync' in registration) {
try {
// Register the periodic background sync.
await registration.periodicSync.register('content-sync', {
// An interval of one day.
minInterval: 24 * 60 * 60 * 1000,
});
available.hidden = false;
notAvailable.hidden = true;
// List registered periodic background sync tags.
const tags = await registration.periodicSync.getTags();
if (tags.length) {
ul.innerHTML = '';
}
tags.forEach((tag) => {
const li = document.createElement('li');
li.textContent = tag;
ul.append(li);
});
// Update the user interface with the last periodic background sync data.
const backgroundSyncCache = await caches.open('periodic-background-sync');
if (backgroundSyncCache) {
const backgroundSyncResponse =
backgroundSyncCache.match('/last-updated');
if (backgroundSyncResponse) {
lastUpdated.textContent = `${await fetch('/last-updated').then(
(response) => response.text()
)} (periodic background-sync)`;
}
}
// Listen for incoming periodic background sync messages.
navigator.serviceWorker.addEventListener('message', async (event) => {
if (event.data.tag === 'content-sync') {
lastUpdated.textContent = `${await updateContent()} (periodic background sync)`;
}
});
} catch (err) {
console.error(err.name, err.message);
available.hidden = true;
notAvailable.hidden = false;
lastUpdated.textContent = 'Never';
}
} else {
available.hidden = true;
notAvailable.hidden = false;
lastUpdated.textContent = `${await updateContent()} (manual)`;
}
};
if ('serviceWorker' in navigator) {
window.addEventListener('load', async () => {
const registration = await navigator.serviceWorker.register('./sw.js');
console.log('Service worker registered for scope', registration.scope);
await registerPeriodicBackgroundSync(registration);
});
}