Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why my Service Worker is always waiting to activate?

I have this very basic question

I'm striving to understand the Service Worker life cycle, or even better, what in practical terms initialize and change the states.

I got 2 questions right now:

1 - in chrome://inspect/#service-workers there are always 2 ou 3 lines, showing service workers all running with the same PID. Why? Why not only one?

2- When i inspect my service worker on refresh i got this:

  • #566 activated and is running [stop]
  • #570 waiting to activate [skipWaiting]

What does that mean? What is 566 and what is 570? I suppose they are instances of the the sw, but why there are two of them? And why 570 is still waiting? What do I have to do to make sure it will be registered-installed-activated?

3- General questions

  • What ends the install event in a normal life cycle?
  • What fires the activate event in a normal life cycle?

index.html

<script>
  if ('serviceWorker' in navigator) {
    window.addEventListener('load', function() {
      navigator.serviceWorker.register('./sw.js')
      .then(function(registration) {
        // successful
        console.log('Success: ', registration);
      }).catch(function(err) {
        // registration failed
        console.log('Error: ', err);
      });
    });
  }
  </script>

sw.js

var cache_name = 'v1';

var cache_files = [
  './',
  './index.html',
  './style.css'
]

self.addEventListener('install', function(e){
  console.log('SW install:', e);
  e.waitUntil(
    caches.open(cache_name)
    .then(function(cache){
      console.log('cache', cache);
      return cache.addAll(cache_files);
    })
    .then(function(cache){
      console.log('Cache completed');
    })
  )
});

self.addEventListener('activate', function(event) {
  console.log('SW activate:', event);
});

self.addEventListener('fetch', function(e){
  console.log('SW fetch:', e.request.url)

  e.respondWith(
    caches.match(e.request)
    .then(function(cache_response){
      if(cache_response) return cache_response;

      return fetch(e.request);
    })
    .catch(function(err){
      console.log('Cache error', err)
    })
  );
});

Thanks!

like image 865
Victor Ferreira Avatar asked Feb 19 '18 03:02

Victor Ferreira


People also ask

How do I activate a service worker?

Install and activate: populating your cacheAfter your service worker is registered, the browser will attempt to install then activate the service worker for your page/site. The install event is fired when an install is successfully completed.

How do I know if a service worker is working?

A: From a page on the same origin, go to Developer Tools > Application > Service Workers. You can also use chrome://inspect/#service-workers to find all running service workers.

How long does a service worker last?

The browser can terminate a running SW thread at almost any time. Chrome terminates a SW if the SW has been idle for 30 seconds.

Do service workers run when browser is closed?

Service workers have a total control over every request made from a website. Since they run in the background, they don't need the webpage to be open. That gives them ability to listen and respond to events such as push messages sent from the server to the browser.


1 Answers

The ids shown by Chrome Devtools are internal. Just to point out. So they name all the Service Workers by an id. That's all.

The reason for having two SWs at the "same time" is that you had one, then you reloaded the page, navigated away and came back, or something along those lines, and you got another one. But at this point in time, when you "just got another one", it has yet to be activated and the previous SW is still controlling the page. The new SW will take control over the previous SW when you navigate back to the site from somewhere else, refreshing the page isn't enough. Basically this means closing all tabs and windows of the page and then loading it again, then the new SW takes over.

The time when the new SW hasn't taken over is called waiting state which happens between installation and activation. That can be skipped by calling self.skipWaiting() from inside the install handler of the SW.

The basic idea behind this flow is the page shouldn't be controlled by a SW that didn't control the page when the page was loaded – for this reason the first visit to a site that registers an SW will not be controlled by that SW, only the second time the SW will be activated etc.

You should REALLY read this brilliant article: The Service Worker Lifecycle

like image 72
pate Avatar answered Oct 02 '22 03:10

pate