Workbox SW: Runtime caching not working until second Reload
Asked Answered
O

2

6

I am new to service worker and workbox. I am currently using the workbox to precache my static assets files, which works fine and I expect my other thirdparty URL to be cached too during runtime, but not working until my second reload on the page:(

Shown Below is the copy of the Code of my Service Worker, please note that I replace my original link to abc.domain.com intentionally :)

workbox.routing.registerRoute(
  //get resources from any abc.domain.com/
  new RegExp('^https://abc.(?:domain).com/(.*)'),
  /*
  *respond with a cached response if available, falling back to the network request if it’s not cached. 
  *The network request is then used to update the cache.
  */
  workbox.strategies.staleWhileRevalidate({
    cacheName: 'Bill Resources',
    maxEntries: 60,
    maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days
  }),
); 

workbox.routing.registerRoute(
  new RegExp('^https://fonts.(?:googleapis|gstatic).com/(.*)'),
  //serve from network first, if not availabe then cache
  workbox.strategies.networkFirst(),
); 

workbox.routing.registerRoute(
  new RegExp('^https://use.(?:fontawesome).com/(.*)'),
  //serve from network first, if not availabe then cache
  workbox.strategies.networkFirst(),
); 

I have cleared storage times without number, I refreshed cache storage from google developer tools, but all seems to be the same. Resources from a custom link, google fonts and fontawesome, fail to be cached the first time. Below is the console and the Cache Storage Tab for my page first load image and the second load Image respectively.

First Load Second Load

Please I dont know what I am doing wrong and why it behaves like so.

Thanks in Advance

Ockeghem answered 18/4, 2018 at 10:18 Comment(2)
reading this may help , and the steps <install, register, activate > must all occur for your refresh of cache. So the page refresh may be feature of lifecycle.... blog.sessionstack.com/…Holoenzyme
Thanks@RobertRowntree, but I think my service worker is installed, registered and registered properly, and it still behave like such and there is no error message printed on the consoleOckeghem
H
1

This is expected behaviour.

The way service workers get set up is that they will have an install and activate phase, where installation can happen when ever a new service worker is registered or a service worker updates.

A service worker will then activate when it's safe to do so (i.e. no windows are currently being "controlled" be a service worker).

Once a service worker is activated, it'll control any new pages.

What you are seeing is:

  1. Page is loaded and the page registers a service worker
  2. The service worker precaches any files during it's install phase
  3. A service activates but isn't controlling any pages
  4. You refresh the page and at this point the page is controlled and requests will go through the service worker (resulting in the caching on the second load).
Hermosillo answered 18/4, 2018 at 17:52 Comment(3)
Thanks @GauntFace, I tried writing my own JavaScript without using workbox, though it fetches no event request at first load until the second time, then I use self.clients.claim(), It fetches the events at the first load. self.addEventListener('install', function(event) { console.log('I am installed') }); self.addEventListener('fetch', function(event) { console.log("Fetching"+event.request) }); self.addEventListener('activate', function (event) { event.waitUntil(self.clients.claim()); }); So, I tried using workbox.clientsClaim(); for workbox and its still not working.Ockeghem
I want the service worker to be controlling the page at the first load beacuase, when a user visit my site the first, I want the external URL to be cached, so that when they go offline after that first load, all the external links should be ready and be loaded for them.Ockeghem
You can't have the SW controlling on the first load because the page has to load before it can register the SW. You may find different behaviour because you're example isn't pulling in any files where as workbox is. clientsClaim() will make the service worker control the page immediately (i.e. no refresh) but this will be AFTER the page has already loaded, meaning it won't see the requests.Hermosillo
L
3

The service worker will not cache anything until its been activated. It gets activated only on the second hit itself. To achieve caching on the first hit you have to guide service worker to skip waiting for activation. you can do this by

self.addEventListener('install', () => {
   self.skipWaiting(); //tells service worker to skip installing and activate it
   /*your code for pre-caching*/
});

once its been skipped it enter the activated mode and will wait for caching but it wont cache the clients interaction. To do so apply the following line

self.addEventListener('activate', () => {
     clients.claim();
});

which starts caching on the first hit itself

Legate answered 1/3, 2019 at 5:41 Comment(0)
H
1

This is expected behaviour.

The way service workers get set up is that they will have an install and activate phase, where installation can happen when ever a new service worker is registered or a service worker updates.

A service worker will then activate when it's safe to do so (i.e. no windows are currently being "controlled" be a service worker).

Once a service worker is activated, it'll control any new pages.

What you are seeing is:

  1. Page is loaded and the page registers a service worker
  2. The service worker precaches any files during it's install phase
  3. A service activates but isn't controlling any pages
  4. You refresh the page and at this point the page is controlled and requests will go through the service worker (resulting in the caching on the second load).
Hermosillo answered 18/4, 2018 at 17:52 Comment(3)
Thanks @GauntFace, I tried writing my own JavaScript without using workbox, though it fetches no event request at first load until the second time, then I use self.clients.claim(), It fetches the events at the first load. self.addEventListener('install', function(event) { console.log('I am installed') }); self.addEventListener('fetch', function(event) { console.log("Fetching"+event.request) }); self.addEventListener('activate', function (event) { event.waitUntil(self.clients.claim()); }); So, I tried using workbox.clientsClaim(); for workbox and its still not working.Ockeghem
I want the service worker to be controlling the page at the first load beacuase, when a user visit my site the first, I want the external URL to be cached, so that when they go offline after that first load, all the external links should be ready and be loaded for them.Ockeghem
You can't have the SW controlling on the first load because the page has to load before it can register the SW. You may find different behaviour because you're example isn't pulling in any files where as workbox is. clientsClaim() will make the service worker control the page immediately (i.e. no refresh) but this will be AFTER the page has already loaded, meaning it won't see the requests.Hermosillo

© 2022 - 2024 — McMap. All rights reserved.