1. Introduction
This section is non-normative.
Web Applications often run in environments with unreliable networks (e.g., mobile phones) and unknown lifetimes (the browser might be killed or the user might navigate away). This makes it difficult for web apps to keep their content and state in sync with servers.
This API is intended to reduce the time between content creation and content synchronization between the servers and the web app. It does so by letting the web app register an intent to periodically synchronize state and data, with a minimum interval it wishes to do so at. Through a service worker event, the user agent then periodically lets the web app download network resources and update state.
As this API relies on service workers, functionality provided by this API is only available in a secure context.
1.1. Example
Registering periodic background sync at a mininimum interval of one day from a browsing context:async function registerPeriodicNewsCheck() { const registration= await navigator. serviceWorker. ready; try { await registration. periodicSync. register( 'fetch-news' , { minInterval: 24 * 60 * 60 * 1000 , }); } catch { console. log( 'Periodic Sync could not be registered!' ); } }
Reacting to a periodicsync event within a service worker:
self. addEventListener( 'periodicsync' , event=> { event. waitUntil( fetchAndCacheLatestNews()); });
In the above example fetchAndCacheLatestNews
is a developer-defined function is a developer-defined function that fetches the latest news articles from a server and stores them locally, for example using the Cache
API, for offline consumption.
2. Concepts
When a periodicsync event is fired for a periodic sync registration registration, it is considered to run in the background if no service worker clients whose frame type is "top-level
", "auxiliary
" or "nested
" exist for the origin of the service worker registration associated with registration.
3. Extensions to service worker registration
A service worker registration additionally has:-
Active periodic sync registrations (a map), where each key is a
DOMString
, and each item is a periodic sync registration. -
Periodic sync processing queue, initially the result of starting a new parallel queue.
4. Constructs
4.1. Periodic sync registration
A periodic sync registration consists of:A tag, which is a DOMString
.
Note: Periodic Background Sync doesn’t share namespace with Background Sync, so an origin can have registrations of both types with the same tag.
minimum interval (a long long), which is used to specify the minimum interval, in milliseconds, at which the periodic synchronization should happen. minimum interval is a suggestion to the user agent.
Note: The actual interval at which periodicsync events are fired MUST be greater than or equal to this.
An anchor time (a timestamp), the previous time a periodicsync event fired for this periodic sync registration, or the time of initial registration.
A state, which is one of "pending
", "firing
", "suspended
" or "reregistered-while-firing
". It is initially set to "pending
".
4.2. Periodic Sync Scheduler
The periodic sync scheduler is responsible for scheduling firing of periodicsync events. In response to these triggers, the scheduler either schedules delayed processing to fire a periodicsync event at the appropriate time in the future, or cancels such scheduling.-
The time of last fire, a map, where each key is an origin, and each item is a timestamp. The keys of this map are the origins associated with the service worker registrations of active periodic sync registrations. This is initially an empty map.
The effective minimum sync interval for origin origin (an origin), is the minimum periodic sync interval for any origin + some user agent defined amount for the origin.
Note: The user agent defined amount could be based off the amount of engagement the user has with the origin. This value can be different each time effective minimum sync interval for origin is called.
The scheduler processes periodic sync registrations.
Note: Browsers may suspend this processing loop when there are no active periodic sync registrations to conserve resources.
4.3. Constants
As recommended in § 5 Privacy Considerations and § 6 Resource Usage, the user agent SHOULD also define:-
minimum periodic sync interval for any origin, a long long, that represents the minimum gap between periodicsync events for any given origin, and,
-
minimum periodic sync interval across origins, a long long, that represents the minimum gap between periodicsync events across all origins.
minimum periodic sync interval across origins MUST be greater than or equal to minimum periodic sync interval for any origin. If undefined, these are set to 43200000, which is twelve hours in milliseconds.
Note: Two caps on frequency are needed because conforming to the cap enforced by minimum periodic sync interval for any origin for each origin can still cause the browser to fire periodicsync events very frequently. This can happen, for instance, when there are many periodic sync registrations for different origins. minimum periodic sync interval across origins ensures there’s a global cap on how often these events are fired.
The user agent MAY define a maximum number of retries, a number, allowed for each periodicsync event. In choosing this, the user agent SHOULD ensure that the time needed to attempt the maximum number of retries is an order of magnitude smaller than the minimum periodic sync interval for any origin. If undefined, this number is zero.
5. Privacy Considerations
5.1. Permission
Periodic Background Sync is only available if thePermissionState
for a PermissionDescriptor
with name
"periodic-background-sync"
is granted
. In addition, user agents SHOULD offer a way for the user to disable Periodic Background Sync.
When Periodic Background Sync is disabled, periodicsync events MUST NOT be dispatched for the periodic sync registrations affected by this permission. (See § 7.2 Respond to permission revocation).
5.2. Location Tracking
Fetch requests within the periodicsync event while in the background may reveal the client’s IP address to the server after the user has left the page. The user agent SHOULD limit tracking by capping the number of retries and duration of periodicsync events, to reduce the amount of time the user’s location can be tracked by the website. Further, the user agent SHOULD limit persistent location tracking by capping the frequency of periodicsync events, both for an origin, and across origins.5.3. History Leaking
Fetch requests within the periodicsync event while in the background may reveal something about the client’s navigation history to middleboxes on networks different from the one used to create the periodic sync registration. For instance, the client might visit site https://example.com, which registers a periodicsync event, but based on the implementation, might not fire until after the user has navigated away from the page and changed networks. Middleboxes on the new network may see the fetch requests that the periodicsync event makes. The fetch requests are HTTPS so the request contents will not be leaked but the destination of the fetch request and domain may be (via DNS lookups and IP address of the request). To prevent this leakage of browsing history, the user agent MAY choose to only fire periodicsync events on the network the periodic sync registration was made on, with the understanding that it will reduce usability by not allowing synchronization opportunistically.6. Resource Usage
This section is non-normative.
A website will most likely download resources from the network when processing a periodicsync event. The underlying operating system may launch the user agent to dispatch these events, and may keep it awake for a pre-defined duration to allow processing of the events. Both cause battery drain. The user agent should cap the duration and frequency of these events to limit resource usage by websites when the user has navigated away.
Large resources should be downloaded by registering a background fetch via the BackgroundFetchManager
interface.
In addition, the user agent should consider other factors such as user engagement with the origin, and any user indications to temporarily reduce data consumption, such as a Data Saving Mode, to adjust the frequency of periodicsync events.
7. Algorithms
7.1. Process periodic sync registrations
When the user agent starts, run the following steps in parallel:-
While true:
-
Let firedPeriodicSync be false.
-
While firedPeriodicSync is false:
-
Wait for some user agent defined amount of time.
Note: This can be used to group synchronization for different periodic sync registrations into a single device wake-up.
-
Wait until online.
-
For each service worker registration registration that is not unregistered, enqueue the following steps to registration’s periodic sync processing queue:
-
Let origin be the origin associated with periodicSyncRegistration’s service worker registration.
-
If time of last fire[origin] + the effective minimum sync interval for origin origin is greater than now, continue.
-
For each periodic sync registration periodicSyncRegistration in registration’s active periodic sync registrations:
-
If periodicSyncRegistration’s state is not "
pending
", continue. -
If periodicSyncRegistration’s anchor time + periodicSyncRegistration’s minimum interval is greater than now, continue.
-
Set firedPeriodicSync to true.
-
Fire a periodicsync event for periodicSyncRegistration.
-
-
-
7.2. Respond to permission revocation
To respond to revocation of the permission withname
"periodic-background-sync"
for origin origin, the user agent MUST enqueue the following steps to the periodic sync processing queue:
-
For each periodic sync registration registration in active periodic sync registrations whose service worker registration is associated with the same origin as origin:
-
Remove registration from active periodic sync registrations.
-
8. API Description
8.1. Extensions to the ServiceWorkerGlobalScope
interface
partial interface ServiceWorkerGlobalScope {attribute EventHandler ; };
onperiodicsync
8.2. Extensions to the ServiceWorkerRegistration
interface
ServiceWorkerRegistration/periodicSync
In only one current engine.
OperaNoneEdge80+
Edge (Legacy)NoneIENone
Firefox for AndroidNoneiOS SafariNoneChrome for Android80+Android WebView80+Samsung Internet13.0+Opera MobileNone
[Exposed =(Window ,Worker )]partial interface ServiceWorkerRegistration {readonly attribute PeriodicSyncManager periodicSync ; };
ServiceWorkerRegistration
has a periodic sync manager (a PeriodicSyncManager
).
The periodicSync
attribute’s getter must return the context object's periodic sync manager, initially a new PeriodicSyncManager
whose service worker registration is the context object's service worker registration.
8.3. PeriodicSyncManager
interface
In only one current engine.
Opera67+Edge80+
Edge (Legacy)NoneIENone
Firefox for AndroidNoneiOS SafariNoneChrome for Android80+Android WebView80+Samsung Internet13.0+Opera Mobile57+
[Exposed =(Window ,Worker )]interface {
PeriodicSyncManager Promise <undefined >register (DOMString ,
tag optional BackgroundSyncOptions = {});
options Promise <sequence <DOMString >>getTags ();Promise <undefined >unregister (DOMString ); };
tag dictionary { [
BackgroundSyncOptions EnforceRange ]unsigned long long = 0; };
minInterval
PeriodicSyncManager
has a service worker registration (a service worker registration). In only one current engine.
Opera67+Edge80+
Edge (Legacy)NoneIENone
Firefox for AndroidNoneiOS SafariNoneChrome for Android80+Android WebView80+Samsung Internet13.0+Opera Mobile57+
register(tag, options)
method, when invoked, MUST return a new promise promise and enqueue the following steps to the periodic sync processing queue:
-
Let serviceWorkerRegistration be the service worker registration associated with the context object's
PeriodicSyncManager
. -
If serviceWorkerRegistration’s active worker is null, reject promise with an
InvalidStateError
and abort these steps. -
If the
PermissionState
for aPermissionDescriptor
withname
"periodic-background-sync"
is notgranted
, reject promise with aNotAllowedError
and abort these steps. -
Let isBackground, a boolean, be true.
-
For each client in the service worker clients for the serviceWorkerRegistration’s origin:
-
If client’s frame type is "
top-level
" or "auxiliary
", set isBackground to false.
-
-
If isBackground is true, reject promise with an
InvalidAccessError
and abort these steps. -
Let currentRegistration be the periodic sync registration in serviceWorkerRegistration’s active periodic sync registrations whose tag equals tag if it exists, else null.
-
If currentRegistration is null:
-
Let newRegistration be a new periodic sync registration.
-
Set newRegistration’s tag to tag.
-
Set newRegistration’s minimum interval to options’
minInterval
member. -
Set newRegistration’s state to "
pending
". -
Set newRegistration’s service worker registration to serviceWorkerRegistration.
-
Set newRegistration’s anchor time to a timestamp representing now.
-
Add newRegistration to serviceWorkerRegistration’s active periodic sync registrations.
-
Resolve promise.
-
-
Else:
-
If currentRegistration’s minimum interval is different to options’
minInterval
member:-
Set currentRegistration’s minimum interval to options’
minInterval
member.
-
-
Else, if currentRegistration’s state is "
firing
", set serviceWorkerRegistration’s state to "reregistered-while-firing
". -
Resolve promise.
-
In only one current engine.
Opera67+Edge80+
Edge (Legacy)NoneIENone
Firefox for AndroidNoneiOS SafariNoneChrome for Android80+Android WebView80+Samsung Internet13.0+Opera Mobile57+
getTags()
method when invoked, MUST return a new promise promise and enqueue the following steps to the periodic sync processing queue:
-
Let serviceWorkerRegistration be the service worker registration associated with the context object's
PeriodicSyncManager
. -
Let currentTags be a new list.
-
For each registration of serviceWorkerRegistration’s active periodic sync registrations, append registration’s tag to currentTags.
-
Resolve promise with currentTags.
PeriodicSyncManager/unregister
In only one current engine.
Opera67+Edge80+
Edge (Legacy)NoneIENone
Firefox for AndroidNoneiOS SafariNoneChrome for Android80+Android WebView80+Samsung Internet13.0+Opera Mobile57+
unregister(tag)
method when invoked, MUST return a new promise promise and enqueue the following steps to the periodic sync processing queue:
-
Let serviceWorkerRegistration be the service worker registration associated with the context object's
PeriodicSyncManager
.-
Let currentRegistration be the periodic sync registration in serviceWorkerRegistration’s active periodic sync registrations whose tag equals tag if it exists, else null.
-
If currentRegistration is not null, remove currentRegistration from serviceWorkerRegistration’s active periodic sync registrations.
-
Resolve promise.
-
8.4. The periodicsync event
PeriodicSyncEvent/PeriodicSyncEvent
In only one current engine.
Opera67+Edge80+
Edge (Legacy)NoneIENone
Firefox for AndroidNoneiOS SafariNoneChrome for Android80+Android WebView80+Samsung Internet13.0+Opera Mobile57+
In only one current engine.
Opera67+Edge80+
Edge (Legacy)NoneIENone
Firefox for AndroidNoneiOS SafariNoneChrome for Android80+Android WebView80+Samsung Internet13.0+Opera Mobile57+
dictionary :
PeriodicSyncEventInit ExtendableEventInit {required DOMString ; }; [
tag Exposed =ServiceWorker ]interface :
PeriodicSyncEvent ExtendableEvent {(
constructor DOMString ,
type PeriodicSyncEventInit );
init readonly attribute DOMString tag ; };
In only one current engine.
Opera67+Edge80+
Edge (Legacy)NoneIENone
Firefox for AndroidNoneiOS SafariNoneChrome for Android80+Android WebView80+Samsung Internet13.0+Opera Mobile57+
PeriodicSyncEvent
has a tag (a tag).
The tag
attribute must return the value it was initialized to. 8.4.1. Fire a periodicsync event
Note: A user agent MAY impose a time limit on the lifetime extension and execution time of aPeriodicSyncEvent
which is stricter than the time limit imposed for ExtendableEvent
s in general. In particular, any retries of the PeriodicSyncEvent
MAY have a significantly shortened time limit.
-
Let serviceWorkerRegistration be registration’s service worker registration.
-
If registration is no longer part of serviceWorkerRegistration’s active periodic sync registrations, abort these steps.
-
Let retryCount be 0.
-
Set registration’s state to "
firing
". -
While true:
-
Let continue be false.
-
Let success be false.
-
Fire functional event "
periodicsync
" usingPeriodicSyncEvent
on serviceWorkerRegistration with tag set to registration’s tag. Let dispatchedEvent, anExtendableEvent
, represent the dispatched periodicsync event and run the following steps with dispatchedEvent: -
Let waitUntilPromise be the result of waiting for all of dispatchedEvent’s extend lifetime promises.
-
React to the fulfillment of waitUntilPromise with the following steps:
-
Set success to true.
-
Set continue to true.
-
-
React to rejection rejection of waitUntilPromise with the following steps:
-
Set continue to true.
-
-
-
Wait for continue to be true.
-
Let origin be the origin associated with registration’s service worker registration.
-
If success is true, set time of last fire for key origin to the current time.
-
If success is true or retryCount is greater than maximum number of retries or registration’s state is "
reregistered-while-firing
", then:-
Set registration’s state to "
pending
". -
Set registration’s anchor time to a timestamp representing now.
-
Abort these steps.
-
-
-
Increment retryCount.
-
Wait for a small back-off time based on retryCount.
-