A Service worker is basically a script (JavaScript file) that runs in background and assists in offline first web application development. A Service worker can not directly interact with the webpage nor it can directly access the DOM as it runs on a different thread but can communicate with webpages through messages (Post Messages).

Service workers have been designed to be fully asynchronous, as a consequence, APIs such as synchronous XHR and localStorage can’t be used inside a service worker. But since it is working on a different thread it doesn’t block your application in any way.

Service workers are terminated when not in use and restored when required. It acts as a programmable network proxy, allowing developers to handle how network requests from the web page is handled. So the developers can take appropriate action based on the availability of network.

Note that if you have never used promises before, better read about them first as service workers use promises intensively.

Browser Support for Service Workers?

Almost all of the major browsers today support service workers. If you would like to check which browsers support which API’s of service works head over to IsServiceWorkerReady.

Service Worker v/s Web Worker

Both Service workers and Web workers are JavaScript workers with lots of similarities but there are a few difference too.

Service workers are designed to handle network requests and assist in offline first development, Push Notifications and background syncs. Communication’s with the webpage must go through service workers PostMessage method.

Web workers mimics the multi-threading model, allowing complex / data or processor intensive tasks to run in background. Ideal to keep your UI jank free when you have to deal with a lot of computations. Communication’s with the webpage must go through web workers PostMessage method.

Registering a Service Worker

To register a service worker we first check if the browser supports it and then register it.

if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/ServiceWorker.js')
.then(function(response) {

// Service worker registration done
console.log('Registration Successful', response); }, function(error) { // Service worker registration failed
console.log('Registration Failed', error); }

Service workers can be registered on each page load without concern, the browser will handle, if the registration is required or not.

Registration life cycle consists of 3 steps:

  1. Download
  2. Install
  3. Activate

A service worker is downloaded when a user accesses the webpage and installation is done if the file is found to be new. After that it is immediately activated.

Network Handling

self.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request)
.then(function(response) {
// Cache hit - return response
if (response) {
return response;
}
return fetch(event.request);
}
)
);
});

After the service worker is installed, upon page refresh or navigation the service worker will begin fetching data and caching. let us look at an example, that fetches image from some other website using service worker.

self.addEventListener('fetch', function(event) {
if (/\.jpg$/.test(event.request.url)) {
event.respondWith(
fetch('//www.medium.co.uk/images/itachi.jpg', {
mode: 'no-cors'
})
);
}
});

In the above code, on every network request that end in .jpg we are displaying an image of itachi. Also we have ‘no-cors’ mode enabled so even if the headers are not CORS enabled we can use the response.

Ending Notes

  • JavaScript Worker
  • Programmable network proxy
  • Fully asynchronous
  • HTTPS only
  • Can not directly access DOM or web page
  • Data inside service workers is not persisted