Day 1- easy pizzy boy I'm nearly dizzy

Day 1- easy pizzy boy I'm nearly dizzy

Service what??

A service worker is a very essential component to progressive web apps.

For a progressive web app that features push notifications, offline experiences, background syncs, network request handling (fetch requests)- a service worker is the yin to it's yang.

How they work

A Service worker runs in the background, separate from the webpage, has no DOM access, and involves uhmm one or two promises.

How it's done

1. I cached my page assets in a file I named index.sw.js

See snippet below:

const CACHE_NAME = 'SITE_CONTENT_V1';

const urlsToCache = [

    '/index.html',

    '/style/fonts.css',
    '/style/layout.css',
    '/style/pages.css',

    '/scripts/index.js',
    '/scripts/learn.js',
    '/scripts/localstorage.js',

    '/css/app.css',
    '/css/bootstrap.css',
    '/css/bootstrap.min.css',

    '/js/bootstrap.js',
    '/js/bootstrap.min.js',

];

2. Next, I registered the service worker script in a separate file.

The code runs an async (arrow)function wrapped in a try-catch block once the page loads.

Console logs the corresponding message for if the registration is successful or not.

See snippet below

if ('serviceWorker' in navigator) {
  window.addEventListener('load', async () => {
      try {
          const registration = await navigator.serviceWorker.register('index.sw.js');
          console.log('Service worker registration sucessful');
          console.log(`Registered with scope: ${registration.scope}`);
      } catch (e) {
          debugger;
          console.log('Service worker registration failed');
          console.log(e);
      }
  });
}

3. Next I installed the service worker

Right below my cached assets, I ran an install event which ensures that the assets/files are successfully cached, then installs the service worker.

See snippet below

self.addEventListener('install', installer  => {
    console.log('Installing');

    const done = async () => {
        const cache = await caches.open(CACHE_NAME);
        return cache.addAll(urlsToCache);
    };

    installer.waitUntil(done());
});

4. Now it's time to write the fetch event

Once a user visits the page and refreshes or navigates to another part of the page, the service worker kicks off in the background and begins to receive fetch requests to return the pages that were cached earlier, or make a network request, or show the offline page if a server error is encountered.

Notice role of response = await caches.match(request); before the try-catch block in the code snippet below

self.addEventListener('fetch', fetchEvent => {
    const url = fetchEvent.request.url;
    console.log(`Fetching: ${url}`);

    const getResponse = async (request) => {
        let response;

        response = await caches.match(request);
        if(response && response.status === 200) {
            console.log('File in cache. Returning cached version.');
            return response;
        }

        try {
            response = await fetch(request);
            if(response && response.status === 404) {
                return caches.match('/service-workers/404.html');
            }
        } catch (e) {
            return caches.match('/service-workers/offline.html')
        }

        const clone = response.clone();
        const cache = await caches.open(CACHE_NAME);
        cache.put(url, clone);
        return response;
    };

5. Finally, updating the service worker using the activate event.

The reason for this is to be able to get rid of redundant files in the cache or a redundant cache.

When this happens, a new install event will occur, creating a new service worker, followed by the activate event.

See snippet below

self.addEventListener('activate', activator => {
    console.log('Activating');

    const currentCaches = [CACHE_NAME];
    const done = async () => {
        const names = await caches.keys();
        return Promise.all(names.map(name => {
            if(!currentCaches.includes(name)) {
                return caches.delete(name);
            }
        }));
    };

    activator.waitUntil(done());

whew!

So did that do it?

Let me know if this helped you, or if this was a good read.

Please share too!

Thanks for reading and see you tumawo!