Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Workbox - runtime cache only created on second page refresh

I'm new to service workers, and I'm using Workbox to precache my app shell and cache my api data.

The precaching of assets is working correctly, with the cache being created and populated.

The runtime caching isn't creating a cache and populating it until I reload the page a second time.

I thought this might be a timing issue, so I set a page reload of the data in the javascript, however this still didn't cache the call.

I'm not doing anything specific to create the cache, app code is:

...
app.getData = function() {
  var requestHeaders = new Headers({
    Accept: "application/json"
  });
  fetch(app.dataUrl, { headers: requestHeaders })
  .then(function(response) {
    return response.json();
  })
  .then(function(json) {
      app.updateCards(json);
  })
  .catch(function(error) {
      console.log('There has been a problem with your fetch operation: ' + error.message);
  });
}
...
if ('serviceWorker' in navigator) {
navigator.serviceWorker
         .register('/my_sw.js')
         .then(function() {
            console.log('Service Worker Registered');
         });
}

app.getData();  # fetch api data

then in the service worker:

 ...
 const workboxSW = new self.WorkboxSW({clientsClaim: true});
 // register data url to cache
 workboxSW.router.registerRoute(
    '/my_api/data',
     workboxSW.strategies.staleWhileRevalidate()
 );
 // pre-cache assets
 workboxSW.precache(fileManifest);

I am using the Chrome Dev tools to check the sw status and the cache created. The network calls to the data URL are as follows:

1st load of page:
enter image description here 2nd load of page:
enter image description here

I'd be grateful for any advice on what I'm doing wrong, or how to debug it.

Thanks in advance
Dan

like image 307
d_a_n Avatar asked Aug 13 '17 17:08

d_a_n


People also ask

What is runtime cache?

Runtime caching refers to gradually adding responses to a cache "as you go". While runtime caching doesn't help with the reliability of the current request, it can help make future requests for the same URL more reliable.

What is self __ Wb_manifest?

Note the self.__WB_MANIFEST string. This is a placeholder that Workbox replaces with the precache manifest. Below is a valid configuration for this use case: // build-sw.js.

What is Cache first strategy?

# Cache first, falling back to network The request hits the cache. If the asset is in the cache, serve it from there. If the request is not in the cache, go to the network. Once the network request finishes, add it to the cache, then return the response from the network.

What is a Precache?

Pronounced "pre-cashing," it refers to software that downloads data ahead of time in anticipation of its use. For example, when a Web page is retrieved, the pages that users typically jump to when they leave that page might be precached in anticipation.


1 Answers

To be safe, you might want to add skipWaitingto the Workbox constructor to ensure the service worker doesn't wait for the page to reload to start caching.

You would also want to wait on serviceWorker.ready in your page before making the API call. This way you know the service worker is active.

These changes together, in your service worker you would have:

 ...
 const workboxSW = new self.WorkboxSW({skipWaiting: true, clientsClaim: true});
 // register data url to cache
 workboxSW.router.registerRoute(
    '/my_api/data',
     workboxSW.strategies.staleWhileRevalidate()
 );
 // pre-cache assets
 workboxSW.precache(fileManifest);

Then in your web page

...
if ('serviceWorker' in navigator) {
    navigator.serviceWorker
      .register('/my_sw.js')
      .then(function() {
        return navigator.serviceWorker.ready;
      })
      .then(function() {
        app.getData();  # fetch api data
      });
}
like image 105
Matt Gaunt Avatar answered Sep 23 '22 18:09

Matt Gaunt