This document provides a collection of use cases for cross origin communication between Service Workers and webpages.

Introduction

This document will use the term navigator.connect() to refer to the notional API that allows cross-origin communication between Service Workers and web pages. This isn't intended to presuppose the final shape of the API, although we don't know of any alternate proposals.

Cross-origin communication between two web pages or between a web page and a Service Worker is currently possible, using an iframe and channel messaging, for example. However, no such direct communication is possible between two Service Workers. The use cases in this document are intended to illustrate how communication between two Service Workers, which is enabled by navigator.connect, creates opportunities for more intelligent, efficient, and elegant web apps and services.

Use-Cases

Offline Analytics

Third party analytics platforms expose their services via REST interfaces. Thus, these platforms are unable to provide insights about offline behavior. As Service Workers and offline web apps become more prevalent, the need for analytics platforms that function offline will continue to grow.

navigator.connect enables third party analytics platforms to register Service Workers that expose APIs to track metrics both online and offline. These Service Workers are then able to report these metrics when connectivity is reestablished so that they can be consumed by the developer. Furthermore, this reporting can be implemented with background sync to take advantage of times when the user’s experience will not be impacted—for example, avoiding saturating the network with non-essential requests when the user is struggling with poor connectivity or on a heavily metered/throttled mobile plan. Thus, exposing analytics APIs via Service Workers allows third party analytics platforms to reduce their performance costs even when online.

Note that without navigator.connect, a web app frontend could report metrics to an analytics platform Service Worker via communication through an iframe. However, a web app’s Service Worker would not be able to communicate with the analytics platform in this way. Web app Service Workers perform crucial tasks—both online and offline—that are valuable for developers to track. navigator.connect enables the Service Worker to Service Worker communication that is necessary for this robust web app analytics model.

Cloud Storage Platforms

Suppose Google Drive offers a Service Worker that provides access to the user’s files in the cloud, as well as a caching mechanism that keeps high priority files available for offline access. We want to implement a web app for offline document reading on both mobile and desktop called Readle.

When the user saves an online document to Readle, Readle’s Service Worker loads the document into temporary storage and uses the Drive API—exposed by the Drive Service Worker via navigator.connect—to save the document to the cloud. Without navigator.connect, Readle’s frontend would have to take care of this work, and the saving of a large document could be interrupted if the frontend were closed prematurely.

Once a document is saved to Drive, it is added to a queue of documents to read with Readle. On desktop, hard drive space can be plentiful, so Readle keeps many documents in the Drive Service Worker’s cache. On mobile, storage is a scarcer resource, so Readle selectively tells the Drive Service Worker to cache only the next few documents in the queue.

Suppose the user reads a few documents from the top of Readle’s queue on her desktop. In a world without navigator.connect, Readle on the user’s mobile device can’t start syncing the new top of the queue until the frontend is loaded. With navigator.connect, Readle can use push messaging to send the new top of the queue to its mobile Service Worker, which can then notify the Drive Service Worker which new documents to cache. With sufficient notice, Drive's Service Worker can intelligently pull down these files in the background such that they are available quickly and offline the next time the user opens Readle on the mobile web.

Shared Fonts

Fonts are a shared resource where latency is critical. People expect the text on a web page to be readable while the images and/or videos load. Latin fonts are 50-200 KB and download in 0.5 to 1.0 seconds, which is sluggish but acceptable. Chinese/Japanese/Korean (CJK) fonts are 4-20 MB and download in 10 to 30+ seconds, which is unacceptably slow.

Having a way to preload and persist fonts locally can provide a much better user experience for CJK (and also Latin) users. The browser cache provides a rudimentary persistence mechanism, allowing a font drawn from a given URL to be retrieved from the server once and served locally many times. However, the browser cache falls short of the ideal implementation. For example, when a font is changed, the browser cache does not realize it is stale until a web page next requests the font. The stale-while-revalidate Cache-Control extension can allow the requesting web page to use the stale font without delay, but the request will cause the new font to be downloaded while the user is actively using the network for other purposes. In an ideal world, the download would be performed intelligently via background sync at a time when bandwidth is abundant and cheap. Additionally, a smarter persistance method would efficiently download the font deltas, which are undoubtedly far smaller than the entire font.

Alternatively to the browser cache, local persistence mechanisms such as IndexedDB can be used to reduce redundant font requests over the network. However, such local persistence mechanisms are domain specific: if the same font is used in multiple domains, it must be persisted separately for each domain.

In contrast, a cross domain service can reduce unnecessary latency and storage costs for fonts (and other such shared resources) with greater customized intelligence than the browser cache. Such a cross domain service can be implemented in the form of a fonts Service Worker and navigator.connect protocols. This implementation opens up additional opportunities as well. For instance, the fonts Service Worker can use the background sync API to schedule rationalization and optimization work when the network and CPU are idle, including:

Note that a shared fonts service could be implemented without navigator.connect, although it would be quite awkward. With navigator.connect, the optimization can happen in the background, with a web app’s Service Worker handling the front end’s font request and communicating with the shared fonts Service Worker as necessary. In this way, navigator.connect enables a transparent and elegant solution that avoids the need to alter CSS loading.

TODO(slightlyoff): add more details on the difference between the with- and without-navigator.connect implementations.

Non-Goals

Extending the Platform

Browsers have a number of ways to expose functionality to web developers. Most commonly, browsers expose standardized Javascript APIs to web pages and Service Workers. However, browsers can expose arbitrary, unstandardized functionality with Javascript APIs as well, although this is uncommon due to the danger of this game. Similarly, browsers can expose platform features via URL endpoints. With current technologies, such exposed APIs could be invoked by web pages through <iframe src="implementation://defined.uri/"> combined with postMessage. navigator.connect could similarly allow such a URL endpoints to be accessed by Service Workers.

However, this use case is a non-goal. It is unlikely to drive aspects of the proposed API. Should exposing platform features to Service Workers via URL endpoints prove valuable in the future, it will require a detailed analysis of how to make it safe for the web before recommending or supporting it.

Security and Privacy Considerations

User agents should not leak any information on sites a user has visited etc to other webpages, unless the visited site opts in. In particular this means that a service rejecting a connection attempt should be indistinguishable from no service being installed to service a particular URL.

If attempting to connect to a service can trigger installation of a service worker, we need to fill in the security and privacy concerns around doing that.

Glossary

Background Sync API
See https://github.com/slightlyoff/BackgroundSync/.
Service Worker
See https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html.
stale-while-revalidate
See http://tools.ietf.org/html/rfc5861#section-3.