= Progressive Web App (PWA) = This document and associated samples will help reproduce the state of the PWA demonstrated at the Evergreen International Conference 2017 by Dan Scott during his talk https://stuff.coffeecode.net/2017/evergreen-progressive-web-app[We aim to misbehave - Evergreen: Progressive Web App]. For a very basic PWA, we need to offer: . a manifest to give browsers the URL, icons, descriptions, and theme they need to launch in a fashion similar to native apps . a service worker that can handle poor or entirely offline network conditions by intercepting network requests and rerouting them to a dedicated local cache (if necessary). By bypassing the network, we can also reduce the overall bandwidth consumed and improve the performance of the application. We will focus on the public catalogue at /eg/opac and specifically the My Account section at /eg/opac/myopac. However, the service worker must be registered at the highest scope to exert control over its assets, and the existence of a number of relevant CSS and JavaScript files under paths like /js and /css means it will have to be registered at the root (/). == Create the service worker == . In the `service-worker` directory, run `npm install` to install the `sw-precache` package. . Adjust `sw-precache.js` to reflect your site's logo files, etc. . Run `node_modules/sw-precache/cli.js --config sw-precache.js` to generate the `service-worker.js` file, based on the configuration in `sw-precache.js` . Copy `service-worker.js` into the `web` directory. . Copy the service worker registration template into the public catalogue templates directory: + [source,bash] ------------------------------------------------------------ cp templates/opac/parts/sw-register.tt2 /openils/var/templates/opac/parts/. ------------------------------------------------------------ + . Add the service worker registration code to the `` section of `templates/opac/parts/base.tt2`: + [source,txt] ------------------------------------------------------------ [% INCLUDE 'opac/parts/sw-register.tt2' %] ------------------------------------------------------------ == Add a manifest == . Add the following lines to `templates/opac/parts/base.tt2`: + [source,html] ------------------------------------------------------------ ------------------------------------------------------------ + . Adjust the manifest details to suit your theme and site name: .. Keep the `name` and `short_name` fields to 12 characters or less, and keep them the same. .. Also match the `theme-color` `` value with the `theme_color` field in the manifest. == Deploy the code! == . Copy the contents of the `web` directory into `/openils/var/web`: + [source,bash] ------------------------------------------------------------ cp -r web/* /openils/var/web/. ------------------------------------------------------------ == Optimizations == If you are running the staff client with requests proxied by nginx, you can take advantage of the support that has been built into modern versions of nginx for the https://http2.github.io/[HTTP/2] protocol and gain the advantages of multiplexing by simply adding 'http2' to your `listen` line: [source,txt] ------------------------------------------------------------ server { listen 443 ssl http2; ------------------------------------------------------------ We're loading Dojo on every page, even though by default the only page that absolutely requires it is the advanced search page. This results in approximately an extra half-second initial page load time, which makes https://developers.google.com/web/tools/lighthouse/[Lighthouse] unhappy about our performance. The https://bugs.launchpad.net/evergreen/+bug/1411699[Don't load Dojo widgets] branch shifts the requirement to only the advanced search page. Our "My Account" pages are currently hard-coded as `Expires: -1` and `Cache-Control: no-store` which makes browsers reluctant to cache them, understandably. The behaviour of the `sw-precache` generator appears to be to respect the header and not cache the request. Commit e7f11d5 in this branch removes the hard-coded setting from `EGCatLoader.pm` and enables us to control this in the HTTP server configuration instead. See https://bugs.launchpad.net/evergreen/+bug/1681095[Extend browser cache-busting branch] for a way to greatly extend the cache expiration for all non-HTML assets while still allowing changes to propagate quickly, if necessary. == Limitations == There are currently many! As the public catalogue currently appends stateful GET params to URLs, even when accessing `My Account`, the cached content can often only be accessed if you follow the same path to access a given page when offline. For example, if you start a session by searching for "Potter", and then click on "My Account", any of the account pages you visit will have a `;query=Potter` param attached to their URL. If you happen to perform a different search, then access "My Account", you may not be able to access the page at all, or you might see different cached results. Searching offline doesn't make much sense anyway. Ideally we would detect when network conditions are bad and serve up an offline page with options greyed out if they are unlikely to work, with highlighting of options that are available offline. == Icon credits == The icons in `web/images` are based on the PWA logo made freely available by Chris Love at https://github.com/docluv/pwa-logo under the terms _The logo should be considered publically available for everyone to use._