Workers at Your Service

Update: A previous version of this post stated the Service Worker API is available in all applications using WKWebView. At this time it is only available in Safari, applications that use SFSafariViewController, and web applications saved to your home screen.

The Service Worker API exposes persistent background processing capabilities to web pages. Support is available in Safari Technology Preview 48, macOS High Sierra 10.13.4 and iOS 11.3 beta seed 2. While WebKit’s implementation and feature set is quickly evolving, we believe it has reached an important milestone in terms of functionality and compliance: applications using service workers for offline support or network/cache optimizations run successfully on latest WebKit builds. Let’s now dive into the specifics of the WebKit Service Worker API implementation.

By specification, service workers and service worker clients are partitioned by their origin. To prevent user cross-site tracking, WebKit further partitions service workers and service worker clients by the top level document origin, the origin shown in the address bar. Frames that are same origin as the top level document will behave the same as in other browser engines. WebKit behaves differently for cross-origin frames. A service worker registered by an example.com iframe inside a webkit.org page will be able to communicate to all service workers and clients that share the same (webkit.org, example.com) partition, but not to any other example.com or webkit.org client. A network load made by a (webkit.org, example.com) service worker will use the same cookies as if the network load was made in an example.com frame embedded in a webkit.org page. Similarly, private browsing mode is enforced in a service worker by partitioning service workers according the browsing session.

The Service Worker API is implemented in WebKit’s multi-process infrastructure which offers both security and performance benefits. Service worker instances run in an isolated service worker process. This process is similar to WebContent processes responsible for rendering web pages and executing arbitrary JavaScript. A separate process, the Storage process, handles the registration, persistency and lifecycle of service workers. As a service worker instance consumes both memory and CPU time, it is important to run them when needed only. Service workers are typically started when being initially registered by a web page. In normal conditions, a service worker will be terminated when there is no service worker client in its partition after a small grace period. Service workers are restarted whenever some interaction is needed, typically in case of postMessage or fetch events.

The Cache API allows storing fetch requests and responses persistently. This is a key API for offline support and proxy-based network optimizations. Similarly to service workers, caches are partitioned by (top origin, frame origin) and browsing session. The current Cache API quota is set to a fixed value of 50 MiB per partition. Once this limit is reached, the web application needs to evict cache entries in order to free space. Both service worker and cache persistent information can be cleared with WebKit APIs. In Safari Technology Preview, this information is put in the ‘Cache’ category of the Privacy preference pane.

Service worker and Cache API stored information will grow as a user is browsing content. To keep only the stored information that is useful to the user, WebKit will remove unused service worker registrations after a period of a few weeks. Caches that do not get opened after a few weeks will also be removed. Web Applications must be resilient to any individual cache, cache entry or service worker being removed.

Web Inspector supports debugging service workers. The ‘Develop’ menu contains the list of running service workers at any time. When clicking on one of the service worker entries, an inspector will be attached to the service worker. From here, you can debug code related to fetch or postMessage events by using breakpoints. The inspector console is also a great place to trigger network loads in the context of the service worker using the fetch API. The service worker caches can be inspected from the console as well with a few lines of code.

We are excited to see service worker applications coming to WebKit and Apple platforms. We encourage you to try the latest implementation and feature set available in Safari Technology Preview 48, macOS High Sierra 10.13.4 beta seed 2, and iOS 11.3 beta seed 2. We want to hear your feedback! File a bug, email [email protected], or tweet to @webkit.