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:asyncfunction 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 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 (which may be Infinity
). The user agent defined amount MUST be used to mitigate the concerns raised in § 5 Privacy Considerations, § 6 Security Considerations and § 7 Resource Usage.
Note: The user agent defined amount can be based on 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. No periodicsync events will fire for a particular origin if the last value returned by effective minimum sync interval for origin is Infinity
.
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
The user agent defines:-
minimum periodic sync interval for any origin, an unsigned long long, that represents the minimum gap between periodicsync events for any given origin in milliseconds, and,
-
minimum periodic sync interval across origins, an unsigned long long, that represents the minimum gap between periodicsync events across all origins in milliseconds.
These constants are used to mitigate the concerns raised in § 5 Privacy Considerations, § 6 Security Considerations and § 7 Resource Usage.
minimum periodic sync interval across origins MUST be greater than or equal to minimum periodic sync interval for any origin. minimum periodic sync interval across origins SHOULD be greater than or equal to 43200000, which is twelve hours in milliseconds.
Note: A minimum value of 43200000 (which is twelve hours in milliseconds) for minimum periodic sync interval across origins is suggested to mitigate the concerns described in § 5 Privacy Considerations and § 6 Security Considerations.
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
. The user agent MAY show UI to the user to ask for this permission. In addition, user agents MUST 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 § 8.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. Security Considerations
Since Periodic Background Sync is a service worker based API, Service Workers §6 Security Considerations apply.In addition, if the origin synchronizes more often than the user visits the site, the origin may be getting more power than the user is aware of or intends. This is because the origin is able to execute code more frequently than the user intends, from within the periodicsync event while in the background. Some of the attacks this opens up are:
-
Cryptocurrency mining: If the web app is able to execute code in the background at a high frequency, a malicious origin may use this CPU power for cryptocurrency mining.
-
Distributed Denial of Service: This is possible if a malicious origin uses periodicsync events on multiple devices to target a specific origin by repeatedly fetching resources from it.
-
A malicious origin can use periodicsync events to abuse the digital advertising ecosystem by fake-clicking on online ads, from a multitude of user devices.
To mitigate the above, the user agent MUST:
-
Gate the capability on
"periodic-background-sync"
permission, as described in § 5.1 Permission. This allows the user to stop firing [periodicsync event|periodicsync events=] for any origin they’ve identified as malicious. -
Impose a time limit on the lifetime extension and execution time of a
PeriodicSyncEvent
which is stricter than the time limit imposed forExtendableEvent
s in general. In particular, any retries of thePeriodicSyncEvent
MAY have a significantly shortened time limit. Note: This time-limited execution of the periodicsync event makes sure this capability cannot be used for crypto mining on behalf of a malicious origin. -
Block registration from contexts where permission UI cannot be shown to the user. (See
register(tag, options)
).
The user agent MUST also impement at least one of the following:
-
Auto-deny the capability to an origin for which the user has not expressed a level of trust.
Note: This trust may be expressed by installing the website as a web app.
-
Cap the interval at which periodicsync events are fired, as described in § 4.3 Constants.
-
Show an audit-style UI to explain to the user how frequently an origin synchronizes content through this API, with appropriate resource attribution.
In addition, the user agent SHOULD:
-
Set effective minimum sync interval for origin in accordance with the user’s engagement level with the origin, as defined in § 4.2 Periodic Sync Scheduler. In particular, this means the implementation stops firing periodicsync events for periodic sync registrations whose associated origin the user has stopped engaging with.
7. 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.
8. Algorithms
8.1. Process periodic sync registrations
When the user agent starts, run the following steps in parallel:-
While true:
-
Wait for minimum periodic sync interval across origins. Note: This can be used to mitigate concerns raised in § 6 Security Considerations.
-
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. This can also be used to mitigate the concerns raised in § 6 Security Considerations.
-
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.
-
-
-
-
8.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.
-
9. API Description
9.1. Extensions to the ServiceWorkerGlobalScope
interface
partial interface ServiceWorkerGlobalScope {attribute EventHandler ; };
onperiodicsync
9.2. Extensions to the ServiceWorkerRegistration
interface
[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.
9.3. PeriodicSyncManager
interface
[Exposed =(Window ,Worker )]interface {
PeriodicSyncManager Promise <void >register (DOMString ,
tag optional BackgroundSyncOptions );
options Promise <sequence <DOMString >>getTags ();Promise <void >unregister (DOMString ); };
tag dictionary { [
BackgroundSyncOptions EnforceRange ]unsigned long long = 0; };
minInterval
PeriodicSyncManager
has a service worker registration (a service worker registration). 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. -
The user agent MAY request permission to use
PermissionName
"periodic-background-sync"
. -
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.
-
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.
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.
-
9.4. The periodicsync event
dictionary :
PeriodicSyncEventInit ExtendableEventInit {required DOMString ; }; [
tag Exposed =ServiceWorker ]interface :
PeriodicSyncEvent ExtendableEvent {(
constructor DOMString ,
type PeriodicSyncEventInit );
init readonly attribute DOMString tag ; };
PeriodicSyncEvent
has a tag (a tag).
The tag
attribute must return the value it was initialized to. 9.4.1. Fire a periodicsync event
-
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.
-