Have questions about images on the web? Tweet your questions to @ChromiumDev with #AskChrome and we'll answer the top questions in our next #AskChrome episode on YouTube.

Experimenting with Periodic Background Sync

What's periodic background sync?

Have you ever been in any of the following situations? Riding a fast train or the subway with flaky or no connectivity, being throttled by your carrier after watching too many videos on the go, or living in a country where bandwidth is struggling to keep up with the demand? If you have, then you’ve surely experienced the frustration of getting certain things done on the web, and wondered why native apps tend to do better in these scenarios.

Native apps can fetch fresh content, such as timely news articles or up-to-date weather information, ahead of time. Even if there’s no network in the subway, you can still read the news. Periodic background sync (PBS) is an experimental feature that gives people the same feature on the web. You can enjoy instant page loads with the latest news from your favorite newspaper, have enough music or videos to entertain yourself during an otherwise boring no-connectivity commute, and more.

Why add periodic background sync to your web app?

Consider a web app that uses a service worker to offer a rich offline experience:

  • When a person launches the app, it may only have stale content loaded.
  • Without periodic background sync, the app can only refresh itself when launched. As a result, people will see a flash of old content being slowly replaced by new content, or just a loading spinner.
  • With PBS, the app can update itself in the background, giving people a smoother and reliably fresh experience.
  • Now people can read the latest news, even in the subway!

Let’s now look at two types of updates that would be beneficial if done ahead of time.

Updating an application

This is the data required for your web app to work correctly.

Examples:

  • Updated search index for a search app.
  • A critical application update.
  • Updated icons or user interface.

Updating content

If your web app regularly publishes updates, you can fetch the newest content to give folks using your site a better experience.

Examples:

  • Fresh articles from news sites.
  • New songs from a favorite artist.
  • Badges and achievements in a fitness app.

Non-goals

Triggering events at a specific time is outside the scope of this API. PBS can't be used for time-based "alarm clock" scenarios.

There is no guaranteed cadence of the periodic sync tasks. When registering for PBS, you provide a minInterval value that acts as a lower bound for the sync interval, but there is no way to guarantee an upper bound. The browser decides this cadence for each web app.

A web app can register multiple periodic tasks, and the frequency determined by the browser for the tasks may or may not end up being the same.

Getting this right

We are putting periodic background sync through a trial period so that you can help us make sure that we got it right. This section explains some of the design decisions we took to make this feature as helpful as possible.

The first design decision we made is that a web app can only use PBS once a person has installed it on their device, and has launched it as a distinct application. PBS is not available in the context of a regular tab in Chrome.

Furthermore, since we don’t want unused or seldom used web apps to gratuitously consume battery or data, we designed PBS such that developers will have to earn it by providing value to their users. Concretely, we are using a site engagement score to determine if and how often periodic background syncs can happen for a given web app. In other words, a periodicsync event won't be fired at all unless the engagement score is greater than zero, and its value will affect the frequency at which the periodicsync event will fire. This ensures that the only apps syncing in the background are the ones you are actively using.

PBS shares some similarities with existing APIs and practices on popular platforms. For instance, one-off background sync as well as push notifications allow a web app's logic to live a little longer (via its service worker) after a person has closed the page. On most platforms, it’s common for people to have installed apps that periodically access the network in the background to provide a better user experience—for critical updates, prefetching content, syncing data, etc. Similarly, periodic background sync also extends the lifetime of a web app's logic to run at regular periods, for what might be a few minutes at a time.

If the browser allowed this to occur frequently and without restrictions, it could result in some privacy concerns. Here's how Chrome has addressed this risk for PBS:

  • The background sync activity only occurs on a network that the device has previously connected to. We recommend to only connect to networks operated by trustworthy parties.
  • As with all internet communications, PBS reveals the IP addresses of the client and the server it's talking to, and the name of the server. To reduce this exposure to roughly what it would be if the app only synced when it was in the foreground, the browser limits the frequency of an app's background syncs to align with how often the person uses that app. If the person stops frequently interacting with the app, PBS will stop triggering. This is a net improvement over the status quo in native apps.

Alternatives

Before PBS, web apps had to jump through hoops to keep content fresh—like triggering a push notification to wake up their service worker and update content as a side effect. But the timing of those notifications is decided by the developer. PBS leaves it to the browser to work with the operating system to figure out when an update should happen, allowing it to optimize for things like power and connectivity state, and prevent resource abuse in the background.

Using PBS instead of push notifications also means that these updates will happen without the fear of interrupting users, which might be the case with a regular notification. Developers still have the option of using push notifications for truly important updates, such as significant breaking news. Users can uninstall the web app, or disable the "Background Sync" site setting for specific web apps if needed.

Origin trial

The current experimental implementation of periodic background sync is available in Chrome 77 and higher. It's implemented as an "origin trial," and you must join the origin trial before it can be enabled for your web app's users.

We anticipate that the trial will end around March 2020, at which point the web platform community can use the feedback collected during the trial to inform a decision about the future of the feature.

During the origin trial, PBS can be tested on all platforms on which Chrome supports installing web apps, including macOS, Windows, Linux, Chrome OS, and Android. On macOS, Windows, and Linux, PBS events will only be fired if an instance of Chrome is actively running. This restriction is similar to how push notifications work on those platforms. If Chrome is quit and then re-launched after multiple background sync intervals have elapsed, a single periodicsync event will be fired soon after Chrome starts up, assuming all other conditions are met.

As part of the origin trial process, the Chrome team welcomes your input. Feedback on the experimental specification can be provided via GitHub, and comments or bug reports on Chrome's implementation can be provided by filing a bug with the Component field set to "Blink>BackgroundSync".

Example code

The following snippets cover common scenarios for interacting with periodic background sync. Some of them are meant to run within the context of your web app, possibly in response to someone clicking a UI element that opts-in to periodic background sync. Other snippets are meant to be run in your service worker's code.

You can see these snippets in context by reading the source code for the live demo.

Checking whether periodic sync can be used

The Permissions API tells you whether PBS can be enabled. You can query for 'periodic-background-sync' permission from either your web app's window context, or from within a service worker.

If the status is 'granted', then your web app meets the requirements to register for PBS.

If the status is anything other than 'granted' (most likely 'denied'), then your web app can't use PBS. This might be because the current browser doesn't support it, or because one of the other requirements outlined above haven't been met.

const status = await navigator.permissions.query({
  name: 'periodic-background-sync',
});
if (status.state === 'granted') {
  // PBS can be used.
} else {
  // PBS cannot be used.
}

Registering a periodic sync

You can register for PBS within your web app's window context, but it must be after the service worker is registered. Both a tag ('content-sync' in the below example) and a minimum sync interval (in milliseconds) are required. You can use whatever string you'd like for the tag, and it will be passed in as a parameter to the corresponding periodicsync event in your service worker. This allows you to distinguish between multiple types of sync activity that you might register.

If you attempt to register when PBS is not supported, the call throw an exception.

const registration = await navigator.serviceWorker.ready;
if ('periodicSync' in registration) {
  try {
    registration.periodicSync.register('content-sync', {
      // An interval of one day.
      minInterval: 24 * 60 * 60 * 1000,
    });
  } catch (error) {
    // PBS cannot be used.
  }
}

Responding to a periodic sync event

To respond to PBS syncs, add a periodicsync event listener to your service worker. The callback parameter contains the tag matching the string you used during registration. This allows you to customize the callback's behavior—like updating one set of cached data as opposed to another—based on different tag values.

self.addEventListener('periodicsync', (event) => {
  if (event.tag === 'content-sync') {
    // See the "Think before you sync" section for
    // checks you could perform before syncing.
    event.waitUntil(syncContent());
  }
  // Other logic for different tags as needed.
});

Checking if a sync with a given tag is registered

You can use the getTags() method to retrieve an array of tag strings, corresponding to active PBS registrations.

One use case is to check whether or not a PBS registration used to update cached data is already active, and if it is, avoid updating the cached data again.

You might also use this method to show a list of active registrations in your web app's settings page, and allow people to enable or disable specific types of syncs based on their preferences.

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 PSB isn't supported, always update.
  updateContentOnPageLoad();
}

Unregistering a previously registered sync

You can stop future periodicsync events from firing by calling unregister() and passing in a tag string that was previously registered.

const registration = await navigator.serviceWorker.ready;
if ('periodicSync' in registration) {
  registration.periodicSync.unregister('content-sync');
}

Think before you sync

When your service worker wakes up to handle a periodicsync event, you have the opportunity to request data, but not the obligation to do so. While handling the event, you may want to take the current network, data saver status, and available storage quota into account before refreshing cached data. You also might structure your code so that there are "lightweight" and "heavyweight" network payloads, depending on those criteria.

The following features can be used inside of a service worker to help make the decision about how much (if anything) to refresh inside your periodicsync handler:

Debugging

It can be a challenge to get the "big picture" view of periodic background sync while testing things locally. information about active registrations, approximate sync intervals, and logs of past sync events can provide valuable context while debugging your web app's behavior. Fortunately, all of that information can be found as an experimental feature in Chrome's DevTools.

Recording local activity

The "Periodic Background Sync" panel's interface is organized around key events in the PBS lifecycle: registering for sync, performing a background sync, and unregistering. In order to obtain information about these events, you need to "start recording" from within DevTools first.

The record button in DevTools

While recording, entries will appear in DevTools corresponding to events, with context and metadata logged for each.

Recorded PBS activity in DevTools

After enabling recording once, it will stay enabled for up to three days, allowing DevTools to capture local debugging information about background syncs that might take place, e.g., hours in the future.

Simulating events

While recording background activity can be helpful, there are times when you'd want to test your periodicsync handler immediately, without waiting for the event to fire on its normal cadence.

You can do this via the "Service Workers" panel within the Applications tab in Chrome DevTools. The "Periodic Sync" field allows you to provide a tag for the event to use, and trigger it as many times as you'd like.

The service workers panel in DevTools

Manually triggering a periodicsync event did not make it into Chrome 77, so the best way to test it out is to use Chrome 78 (currently in Canary) or later. You'll need to follow the same "Enabling the DevTools interface" steps to turn it on.

Live demo

You can try out this live demo app that uses periodic background sync. Make sure that:

  • You're using Chrome 77 or later.
  • You "install" the web app before trying to enable periodic background sync.

(The demo app's author already took the step of signing up for the origin trial.)

References and acknowledgements

This article is adapted from Mugdha Lakhani & Peter Beverloo's original write-up, with contributions from Chris Palmer. Mughda also wrote the code samples, live demo, and the code for the Chrome implementation of this feature.

Enabling the DevTools interface

The following steps are required while periodic background sync remains an origin trial. If and when it progresses out of the origin trial phase, the DevTools interface will be enabled by default.

  • Visit chrome://flags/#enable-devtools-experiments and change the "Developer Tools experiments" setting to "Enabled".
The Developer Tools Experiments flag setting
The settings panel in DevTools
  • In the Experiments section of the Settings panel, enable "Background services section for Periodic Background Sync".
The background service section checkbox in DevTools
  • Close, and then reopen DevTools.
  • You should now see a "Periodic Background Sync" section within the "Application" panel in DevTools.
The periodic background sync panel in DevTools
Was this page helpful?
Yes
What was the best thing about this page?
It helped me complete my goal(s)
Thank you for the feedback. If you have specific ideas on how to improve this page, please create an issue.
It had the information I needed
Thank you for the feedback. If you have specific ideas on how to improve this page, please create an issue.
It had accurate information
Thank you for the feedback. If you have specific ideas on how to improve this page, please create an issue.
It was easy to read
Thank you for the feedback. If you have specific ideas on how to improve this page, please create an issue.
Something else
Thank you for the feedback. If you have specific ideas on how to improve this page, please create an issue.
No
What was the worst thing about this page?
It didn't help me complete my goal(s)
Thank you for the feedback. If you have specific ideas on how to improve this page, please create an issue.
It was missing information I needed
Thank you for the feedback. If you have specific ideas on how to improve this page, please create an issue.
It had inaccurate information
Thank you for the feedback. If you have specific ideas on how to improve this page, please create an issue.
It was hard to read
Thank you for the feedback. If you have specific ideas on how to improve this page, please create an issue.
Something else
Thank you for the feedback. If you have specific ideas on how to improve this page, please create an issue.

rss_feed Subscribe to our RSS or Atom feed and get the latest updates in your favorite feed reader!