Cheers Stephen,
At the moment, I've taken three very wobbly steps into the serviceworkers API necessary for cached PWAs.
See here:
https://sandbox.interaktiv.co.uk/opus-pwa1. The serviceworker is successfully registered - can be seen in the console tab of Chrome Developer Tools using the following code in the header.
Code:
<script>
if ("serviceWorker" in navigator) {
navigator.serviceWorker.register("serviceworker.js")
.then(function(registration) {
console.log("Service Worker registered with scope:", registration.scope);
}).catch(function(err) {
console.log("Service worker registration failed:", err);
});
}
</script>
2. Initially this step simply checked that the fetch process for any URL was successfully intercepted by the serviceworker. But once it was clear that it was working okay, I switch to caching resources using the following code and confirmed by reviewing the appropriate cache storage (ims-cache) in the Application Tab of the Developer Tools in Chrome:
Code:
var CACHED_URLS = [
"index.htm",
"Opus.js",
"9-3.jpg",
"42468.jpg",
"apples3.jpg",
"NoHTML5FallBack.jpg"
];
self.addEventListener("install", function (event) {
event.waitUntil(
caches.open("ims-cache").then(function (cache) {
return cache.addAll(CACHED_URLS);
})
);
});
This is a slightly more advanced version of my initial code that simply cached a single URL.
3. The last step was to retrieve the cached URLs if offline. Again this is a slightly more advanced version that tries to return all the URLs from the cache rather than a single named URL. It's also the least understood and underdeveloped step at the moment. If working, you should be able to reload the PWA when the network is unavailable. This can be triggered using the offline mode in the Network Tab of the Development Tools in Chrome. Additionally, you should monitor this tab to check what is initiating the URL call and if the resource is retrieved from cache.
Code:
self.addEventListener("fetch", function (event) {
event.respondWith(
fetch(event.request).catch(function () {
return caches.match(event.request).then(function (response) {
if (response) {
return response;
} else if (event.request.headers.get("accept").includes("text/html")) {
return caches.match("index.htm");
}
});
})
);
});
Lastly some other points:
a. I'm not supporting this in Opus or promising that it will work. It seemed a little hit and miss when tested.
b. This will only work under localhost or a HTTPS site.
c. Steps 2 & 3 belong in an external JS file named in the code at step one - serviceworker.js.
d. I've not included a source files because I think it's important to build each step and test and review what is happening in the Development Tools of your browser.
e. This is really cool and going to be the next big shift in the web. No more building web apps for different devices - Create an online application with PWA functionality and it will allow your users to continue using your application offline or over slow connections with no loss of user experience.
I found a more advanced tutorial for the first three steps, so I'm going to look at updating my SA example and see if it answers some of the questions I have.
</mack>