Periodic Background Sync API in JavaScript Explained
The Periodic Background Sync API enables Progressive Web Apps (PWAs) to schedule recurring data synchronization tasks that run in the background, even when the web application is closed. This article covers what the Periodic Background Sync API is, how it works alongside service workers, the JavaScript implementation required to register and execute periodic tasks, and the specific browser constraints governing its execution.
What is the Periodic Background Sync API?
The Periodic Background Sync API allows web applications to periodically fetch fresh data, such as news articles, weather updates, or feed content, in the background. Unlike the standard Background Sync API, which triggers a one-time sync as soon as network connectivity is restored, the Periodic Background Sync API triggers sync events at recurring intervals.
This capability reduces load times by pre-fetching data, ensuring users see updated content immediately upon launching the application.
Prerequisites and Browser Requirements
Because background execution consumes device battery and network data, browsers impose strict requirements before allowing periodic synchronization:
- PWA Installation: The application typically must be installed on the user’s device as a PWA.
- Site Engagement Score: Browsers (such as Chromium-based browsers) use a Site Engagement score to determine if the user interacts with the app frequently enough to justify background resource usage.
- HTTPS: The site must be served over a secure HTTPS
connection (or
localhostfor development). - Permissions: The user or browser must grant the
periodic-background-syncpermission.
How JavaScript Schedules Recurring Tasks
Scheduling a periodic task involves two main parts: requesting permission and registering the task in the main application script, and handling the event inside the service worker.
1. Check for Support and Register the Task
In your main application JavaScript file, verify that the browser supports the API, check permissions, and register a periodic sync tag with a minimum interval.
async function registerPeriodicSync() {
const registration = await navigator.serviceWorker.ready;
// Check if Periodic Background Sync is supported
if ('periodicSync' in registration) {
// Check permission status
const status = await navigator.permissions.query({
name: 'periodic-background-sync',
});
if (status.state === 'granted') {
try {
// Register periodic sync with a tag and minimum interval (in milliseconds)
await registration.periodicSync.register('update-latest-news', {
minInterval: 24 * 60 * 60 * 1000, // 24 hours
});
console.log('Periodic background sync registered successfully.');
} catch (error) {
console.error('Periodic background sync registration failed:', error);
}
} else {
console.log('Periodic background sync permission not granted.');
}
} else {
console.log('Periodic Background Sync is not supported by this browser.');
}
}2. Handle the Event in the Service Worker
Once registered, the browser fires the periodicsync
event inside your service worker based on the specified interval and
device conditions.
// service-worker.js
self.addEventListener('periodicsync', (event) => {
if (event.tag === 'update-latest-news') {
event.waitUntil(fetchAndCacheLatestNews());
}
});
async function fetchAndCacheLatestNews() {
try {
const response = await fetch('/api/news/latest');
const data = await response.json();
const cache = await caches.open('news-cache-v1');
await cache.put('/api/news/latest', new Response(JSON.stringify(data)));
console.log('Background sync completed: News cache updated.');
} catch (error) {
console.error('Failed to update news in background:', error);
}
}Managing Registered Tags
You can inspect and remove registered sync tasks using the
getTags() and unregister() methods on the
periodicSync manager.
Retrieve Active Sync Tags
const registration = await navigator.serviceWorker.ready;
if ('periodicSync' in registration) {
const tags = await registration.periodicSync.getTags();
console.log('Active periodic sync tags:', tags);
}Unregister a Sync Tag
const registration = await navigator.serviceWorker.ready;
if ('periodicSync' in registration) {
await registration.periodicSync.unregister('update-latest-news');
console.log('Periodic sync tag removed.');
}Important Execution Behavior
The minInterval parameter is only a suggested minimum
value. The browser does not guarantee exact timing like a traditional
setInterval or server-side cron job. The actual execution
frequency is dynamically calculated by the operating system and browser
based on:
- The device’s battery level and charging state.
- Current network conditions (e.g., whether the device is connected to Wi-Fi).
- How frequently the user opens the application.