Service Workers in Javascript

What is Service Worker:
A service worker is a script that runs independently in the browser background. On the user side, it can intercept its network requests and decide what to load (fetch).
Service workers mainly serve features like background sync, push notifications and they are commonly used for’offline first’ applications, giving the developers the opportunity to take complete control over the user experience.

Before it’s time there has been API called AppCache, which has been trying to serve the offline experience feature. However, there have been numerous problems in the interface of the AppCache API and Service Workers are here, going over them.

The service worker life cycle:
The service worker lifecycle is completely separate from the web page. It’s a programmable network proxy, which is terminated when it’s not used and restarted when it’s next needed. Service Workers heavily rely on the use of Javascript Promises , so it’s good to go over them if they are new to you.



During installation, the service worker can cache some static assets like web pages. If the browser cache the files successfully, the service worker gets installed.

Afterward, the worker needs to be activated. During activation the service worker can manage and decide what to happen to the old caches, typically they are being deleted and replaced with the new versions.

Lastly, after activation, the service worker takes control over all pages in his scope, without the page which initially registered the service worker, which needs to be refreshed. The service worker is smart in terms of memory usage and will be terminated if there is nothing to fetch and there are no message events occurring.

Below is a picture of the place of a service worker between the browser and the network.

service worker request illustrated

The website request chain using Service Worker.

Prerequisites :

  1. HTTPS unless on localhost
    • Service workers require the use of HTTPS connection. Before deployment, the workers does work under the localhost server but if you want to upload it to the internet you need to have the HTTPS setup on your server. One good place to host free demos are the GitHub Pages, which are server over HTTPS.
  2. Browser support
    • Service Workers are highly supported over the internet by Chrome, Firefox, Opera, Safari and Edge, which makes them worthy for deployment.

Registration:
To set up a service worker it needs to be registered. This is done in your page’s Javascript. Once a service worker is registered this will cause the browser to start installing it in the background.

filter_none

edit
close

play_arrow

link
brightness_4
code

// Ensure that the browser supports the service worker API
if (navigator.serviceWorker) {
  // Start registration process on every page load
  window.addEventListener('load', () => {
      navigator.serviceWorker
          // The register function takes as argument
          // the file path to the worker's file
          .register('/service_worker.js')
          // Gives us registration object
          .then(reg => console.log('Service Worker Registered'))
          .catch(swErr => console.log(
                `Service Worker Installation Error: ${swErr}}`));
    });
}

chevron_right


Installing:
After the service worker gets registered it needs to be installed, this is done in the service worker file and where you typically want to fetch your cache assets.

The following steps need to be taken:

  1. Open a cache
  2. Cache the assets
  3. Confirm if the caching is successful
filter_none

edit
close

play_arrow

link
brightness_4
code

var cacheName = 'geeks-cache-v1';
var cacheAssets = [
    '/assets/pages/offline-page.html',
    '/assets/styles/offline-page.css',
    '/assets/script/offline-page.js',
  
];
  
// Call install Event
self.addEventListener('install', e => {
    // Wait until promise is finished 
    e.waitUntil(
        caches.open(cacheName)
        .then(cache => {
            console.log(`Service Worker: Caching Files: ${cache}`);
            cache.addAll(cacheAssets)
                // When everything is set
                .then(() => self.skipWaiting())
        })
    );
})

chevron_right


Activating:

filter_none

edit
close

play_arrow

link
brightness_4
code

// Call Activate Event
self.addEventListener('activate', e => {
    console.log('Service Worker: Activated');
    // Clean up old caches by looping through all of the
    // caches and deleting any old caches or caches that
    // are not defined in the list
    e.waitUntil(
        caches.keys().then(cacheNames => {
            return Promise.all(
                cacheNames.map(
                    cache => {
                        if (cache !== cacheName) {
                            console.log('Service Worker: Clearing Old Cache');
                            return caches.delete(cache);
                        }
                    }
                )
            )
        })
    );
})

chevron_right


Fetching event:
Once the service worker is set up, it should start to interact and use the cached responses. When a particular user navigates through the web pages, the service worker begins to receive fetch events. The following example demonstrates a case when the worker receives a fetch event and search for a matching cache if there is one, it returns the cached file/value, otherwise, it returns the default response of the call to fetch

filter_none

edit
close

play_arrow

link
brightness_4
code

var cacheName = 'geeks-cache-v1';
  
// Call Fetch Event 
self.addEventListener('fetch', e => {
    console.log('Service Worker: Fetching');
    e.respondWith(
        fetch(e.request)
        .then(res => {
            // The response is a stream and in order the browser 
            // to consume the response and in the same time the 
            // cache consuming the response it needs to be 
            // cloned in order to have two streams.
            const resClone = res.clone();
            // Open cache
            caches.open(cacheName)
                .then(cache => {
                    // Add response to cache
                    cache.put(e.request, resClone);
                });
            return res;
        }).catch(
            err => caches.match(e.request)
            .then(res => res)
        )
    );
});

chevron_right


Service Worker can’t:

  • Access the Parent Object
  • Access the Window Object
  • Access the Document Object
  • Access the DOM
  • However, the Service Worker can:

  • Cache Assets & API calls
  • Manage Push Notifications
  • Control the Network Traffic
  • Store the Application Cache
  • Common use cases:

  • Offline-optimized experience
  • Sending Push Notifications
  • Background sync
  • Reference: https://developers.google.com/web/fundamentals/primers/service-workers/



    My Personal Notes arrow_drop_up

    Vice-President at the Computing Society of Edinburgh Napier University

    If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

    Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.


    Article Tags :

    Be the First to upvote.


    Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.