loading...

re: Explain how service workers work like I'm five VIEW POST

FULL DISCUSSION
 

Ooooh boy. This is a challenge. But I'll try.

Service Workers are like little Node.js servers that the browser spins up on-demand. Instead of sending HTTP requests directly to the network, it sends the requests to a JavaScript process that decides what to do with them. The simplest Service Worker acts like a reverse proxy server (aka load balancer). It receives an HTTP request, says "nope, you handle it" and returns the request back to the browser. The next simplest Service Worker is a proxy that simply takes incoming requests, uses fetch(event.request.url) to fetch the response, then does something with that response before passing it back to the browser, which then passes it back to your webpage.

The programming API is very similar to the raw 'http' library in Node, or a "serverless" or "cloud lambda function" API. Here's a quick comparison:

// Node.js
require('http').createServer((request, response) => {
  response.statusCode = 200;
  response.setHeader('Content-Type', 'text/plain');
  response.write("Hello world!", 'utf8');
  response.end();
});
// Service Worker
self.addEventListener('fetch', event =>
  event.respondWith(
    new Response("Hello world!", {
      status: 200,
      headers: {
        'Content-Type': 'text/plain'
      }
    })
  )
);

Okay... so they're not terribly similar in terms of actual syntax. But operationally they are doing nearly the same thing. They respond to every HTTP request with "Hello world!".

Once you realize that a Service Worker is really just a little server running on your client's computer, it's obvious all the crazy things you can do with it. The simplest is to cache results so that your webapp works offline. But you can do all sorts of things, such as redirect requests, modify requests, modify responses. You can make a service worker that transpiles JavaScript using Babel or even modify ExpressJS so you can do server-side template rendering. You can intercept HTTP requests and retrieve the files using Bittorrent.

One thing you can't do though is assume that it is running all the time. It's not. In fact, as soon as you close all the webpages using it, the browser will kill the Service Worker thread. So you can't store state in memory. You have to assume that any moment could be it's last. Maybe it's running on a smartphone, and as soon as the user switches apps or turns of the screen, the browser will kill it to save battery life.

This is a bummer. Because one of the best things about having a server, is you can send stuff to it remotely! Service workers don't have an IP address though. The user's browser can communicate with it, and it can initiate a communication to another server, but how could another server contact your service worker if your service worker isn't always running?

This is where the browser vendors and mobile OS's came up with a great hack. Your service worker can't always be running - that would be terrible for battery life. But their servers - Google's and Apple's - are always running. And the phone's OS is always in contact with those servers (yay privacy's dead!). And the phone's OS can open the phone's web browser. So like the world's geekiest relay, these all coordinate so that you (the website admin) can send a message to an individual service worker running on someone's phone, by sending the message to Google (or Apple's) "push" server, which sends the message to the phone's OS, which shows a notification, which when users click on it opens their browser to your webpage at which point the browser "spins up" your little Service Worker service who receives the "push" event. Since each user has their own Service Worker, you can individualize each push message to be just for them. (Usually by associating their Service Worker with an account on your website.) That way users can choose their own personal notification preferences. Crazy right?!

Code of Conduct Report abuse