-
Notifications
You must be signed in to change notification settings - Fork 8
Service Workers
To allow Malasakit to run offline, the site backend has been designed to serve essentially static pages, with most of the data storage and rendering logic delegated to the client. This design allows service workers to cache pages and static files, which are then served when the client is offline.
At the time of this writing, service workers are a relatively new technology intended replace the deprecated AppCache
standard, so not all browsers may support this feature.
For offline field tests, Google Chrome for Android platforms is recommended.
When a device first connects to Malasakit, a service worker script is installed and caches a predetermined list of pages and files.
The script then monitors outgoing GET
requests, and serves the requested files from the cache when network connectivity is not available.
The purpose of a service worker is to execute JavaScript independent of any page, so the script will run in the background even when the Malasakit site is closed.
Whenever connectivity is available, the cache should be refreshed with the latest set of pages and files.
To determine whether a service worker was successfully installed on a device, disable the device's network connection, then reload the site. The desired page should appear even without a connection.
Service workers can be finicky to test and debug.
Because they are only registered once and run in the background, they must be manually unregistered and reloaded every time a change is made.
This can be done by navigating to chrome://serviceworker-internals
, where a service worker can be unregistered by clicking "Unregister".
Additionally, clicking "Inspect" will bring up a debug console for the service worker.
The service worker API is implemented on top of the promises API.
In short, a Promise
represents a delayed computation.
Each Promise
can be passed callbacks that will be called upon the promise's resolution.
For more information, see the promises API specification,
A service worker must be called from other JavaScript running in a page.
For this reason, a sw-bootstrap.js
script is loaded with every page and calls a sw.js
script that contains the caching logic.
The service worker script (sw.js
, in this case) should have an event listener bound to the install
event.
Upon the event firing, the passed-in callback should open the cache (in a promise), then add all desired resources to the cache.
Each resource is uniquely identified in the cache by the URL path and parameters the resource was requested from.
The script should have an additional event bound to the fetch
event.
This event will fire whenever a request is made on a page in the domain, even for non-GET
methods.
Non-GET
methods should be ignored (some methods, such as the POST
method, cannot even be cached).
In this app, we are using the network first, then cache design. This means that the when a page makes a request, the service worker will first attempt to pull the most up-to-date resources from the server. Cached resources are only served when the request fails (due to a bad connection). An available but intermittent connection may result in several seconds of delay before the request times out and the service worker falls back to using the cache.
For security reasons, a service worker cannot request any resources outside of its own scope, as defined by its URL path.
For example, if the script's URL is /pcari/sw.js
, it can only request other resources that also are in /pcari/
, such as /pcari/resource1.html
or /pcari/static/resource2.html
.
Therefore, Malasakit serves the service worker script as a template from the URL_ROOT
(a special case so that the script has jurisdiction over all other pages).
Browsers also demand that service workers be served over encrypted HTTPS (secure HTTP), and will refuse to run service workers served through an insecure protocol. LetsEncrypt is a good place to start for obtaining a certificate.