This document provides a collection of use cases for cross origin communication between Service Workers and webpages.
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.
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.
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.
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.
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.
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.
stale-while-revalidate