Service workers
Tags: javascript
Published: 2023-08-25 16:39:40

Service workers are a fundamental part of a PWA (Progressive Web App). They enable fast loading (regardless of the network), offline access, push notifications, and other capabilities.

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.

Service Workers heavily rely on the use of Javascript Promises , so it’s good to go over them if they are new to you.

Service workers are specialized JavaScript assets that act as proxies between web browsers and web servers. They aim to improve reliability by providing offline access, as well as boost page performance

Service worker can't access the DOM directly. But it can communicate with the pages it controls by responding to messages sent via the postMessage interface, and those pages can manipulate the DOM.


## Lifecycle

Service workers have a lifecycle that dictates how they are installed, this is separate from your PWA installation. The service worker lifecycle starts with registering the service worker. The browser then attempts to download and parse the service worker file. If parsing succeeds, its install event is fired. The install event only fires once.

Service worker installation happens silently, without requiring user permission, even if the user doesn't install the PWA. The Service Worker API is even available on platforms that do not support PWA installation, such as Safari and Firefox on desktop devices.


You can listen for events in the service worker's global scope using the this object.

```js

// This code executes in its own worker or thread
this.addEventListener("install", event => {
   console.log("Service worker installed");
});
this.addEventListener("activate", event => {
   console.log("Service worker activated");
});

```


## Register a service worker

The first block of code in our app's JavaScript file — `app.js` — is as follows. This is our entry point into using service workers.

```js

const registerServiceWorker = async () => {
  // if condition is to check if service worker are supported for browser
  // "/sw.js" => your actual service worker file which will in public folder

  if ("serviceWorker" in navigator) {
    try {
      const registration = await navigator.serviceWorker.register("/sw.js", {
        scope: "/",
      });
      // life cycle methods
      if (registration.installing) {
        console.log("Service worker installing");
      } else if (registration.waiting) {
        console.log("Service worker installed");
      } else if (registration.active) {
        console.log("Service worker active");
      }
    } catch (error) {
      console.error(`Registration failed with ${error}`);
    }
  }
};

// calling function to register service worker
registerServiceWorker();

```

## Adding files to cache ( so that can be used offline)

```js
const CACHE_NAME = `App-v1`;

// Use the install event to pre-cache all initial resources.
this.addEventListener('install', event => {
  event.waitUntil((async () => {
    const cache = await caches.open(CACHE_NAME);
    cache.addAll([
      '/assets/pages/offline-page.html',
      '/assets/styles/offline-page.css',
      '/assets/script/offline-page.js',
    ]);
  })());
});

```


## Read files when offline

```js
this.addEventListener('fetch', event => {
  event.respondWith((async () => {
    const cache = await caches.open(cacheName);

    // Get the resource from the cache.
    const cachedResponse = await cache.match(event.request);
    if (cachedResponse) {
      return cachedResponse;
    } else {
        try {
          // If the resource was not in the cache, try the network.
          const fetchResponse = await fetch(event.request);

          // Save the resource in the cache and return it.
          cache.put(event.request, fetchResponse.clone());
          return fetchResponse;
        } catch (e) {
          // The network failed.
        }
    }
  })());
});

```
Also can refer:

[GFG](https://www.geeksforgeeks.org/service-workers-in-javascript/)

[Learn PWA](https://web.dev/learn/pwa/)

[Mozilla Docs] (https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API)