2

I'm currently working on a small web app which should implement a cached first scenario (users download the wep app in a wifi provided base and then should be able use it offline outside) I'm not using any framework and therefore implement the caching (SW) myself. As I also integrate some playcanvas content (which has its own loading screen) over an iframe I was wondering what overall strategy in terms of loading would make sense.

In a similar project I simply let the service worker download the assets parallel to the (initial) load of the application. But it came to my mind that that it would be better to implement a workflow which is closer to an native app behavior - meaning showing a overall loading screen during the service worker download process and building/showing my main application after this process is finished (or did fail -> forced network scenario or did happen before -> offline scenario). Another solution would be to show a non blocking "Assets are still being downloaded" banner.

The main thoughts leading mit to the second workflow where:

  • The SW-Loading screen / banner could provide better feedback to the user: "All assets downloaded - I'm safe to go offline", while the old scenario could cause issues here - successfully showing the the user the first state - while some critical files are still downloaded in the back.
  • With the SW-Loading screen the download process is a bit more controllable/understandable for me - as the parallel process of an SW-Download and the Playcanvas Loading for example become sequential.

It would be great if someone could provide me feedback/info:

  • if I'm on the right track with this second scenario for being better or it just being overhead
  • how / if it might be possible to implement a cheap loading screen, meaning for example 100 of 230 Files downloaded or else.
  • better strategies for this scenario in general

As always, thanks for any heads up in advance.

1 Answers1

2

A lot of this comes down to what you want your users to experience. The underlying technology is there to accomplish any of the scenarios you outline.

For instance, if you want to show information about the precaching progress during initial service worker installation, you could do that by adding code along the lines of the following.

In your service worker:

const PRECACHE_NAME = "...";
const URLS_TO_PRECACHE = [
  // ...
];

async function notifyClients(urlsCached, totalURLs) {
  const clients = await self.clients.matchAll({ includeUncontrolled: true });
  for (const client of clients) {
    client.postMessage({ urlsCached, totalURLs });
  }
}

self.addEventListener("install", (event) => {
  event.waitUntil(
    (async () => {
      const cache = await caches.open(PRECACHE_NAME);
      const totalURLs = URLS_TO_PRECACHE.length;
      let urlsCached = 0;

      for (const urlToPrecache of URLS_TO_PRECACHE) {
        await cache.add(urlToPrecache);
        urlsCached++;
        await notifyClients(urlsCached, totalURLs);
      }
    })()
  );
});

In your client pages:

// Optional: if controller is not set, then there isn't already a
// previous service worker, so this is a "first-time" install.
// If you would prefer, you could add this event listener
// unconditionally, and you'll get update messages even when there's an
// updated service worker.
if (!navigator.serviceWorker.controller) {
  navigator.serviceWorker.addEventListener("message", (event) => {
    const { urlsCached, totalURLs } = event.data;
    // Display a message about how many URLs have been cached.
  });
}
Jeff Posnick
  • 53,580
  • 14
  • 141
  • 167