Exploring Service Workers

Service Worker Access

Kyle Simpson

Kyle Simpson

You Don't Know JS
Exploring Service Workers

Check out a free preview of the full Exploring Service Workers course

The "Service Worker Access" Lesson is part of the full, Exploring Service Workers course featured in this preview video. Here's what you'd learn in this lesson:

Kyle writes code to enable access to a service worker based on three possible states: installing, waiting, or active.


Transcript from the "Service Worker Access" Lesson

>> Kyle Simpson: Now, we have a service worker registration. And it is loaded up our service worker, and it's gonna start doing its installation, and running, and all of that. But we need to get access to our service worker, and we're gonna need to be able to communicate with it.

So the way we are gonna first assign our service worker, we don't know at this point what state our service worker.
>> Kyle Simpson: svcworker, we don't know at what state our service worker is in at this point. And the three stages that it could possibly be in are exposed as navigator.serviceworker.installing.

Sorry, it's not navigator.serviceworker. This is our registration. We're going to use swRegistration.installing. If it's not in the installing, it might be in the swRegistration.activating. Actually this is called waiting, sorry. This is called waiting, or the final stage there, state that it could be in sw registration.active. So it can either be installing, waiting or active.

So let's talk about those three states for a moment. Installing is pretty obvious. This is the first time that service worker has been loaded. And by the way, by service worker, we mean that unique configuration of that. So every time we make a change to a service worker, even if it's just a code comment, the browser is gonna think this is an entirely new service worker that has to go through the whole lifecycle it needs to be installed, and all of that.

And if we've updated a service worker or one already existed, now we can have a worker that we could have very easily a site that has. At least two instances of a service worker, which probably sounds like it could be a problem, because it could be. Now we have sort of some chaos, so the way the life cycle works is that you can only have one service worker active at any given moment.

And so by default when a second one has been installed, because you've made a quick small change to it from the last time. When the second one has been installed, it enters a waiting phase. Waiting for the first one to be finished. And the first one is not considered finished, until the lifetime of the page that it was serving has gone away.

So you might think, well if the user just clicks refresh, then that should be good enough. And it turns out by way of nuances of the way that works, you actually have to have a navigation event, like the user has to navigate to some other page before the previous service worker can die.

And then the secondary or the new service worker that's in this waiting stage, immediately activates when the old one dies. So it was installed but it hasn't done anything yet its kind of been in waiting game, and then the old ones goes away and the new one is immediately implied.

That is sometimes what you want, and I think the reason for the default of that sort of wankyness about having to wait for another navigation event. Is that, if you ship out a service worker update to a page, and the page itself wasn't loaded by that service worker, it was loaded by a previous one.

It is possible if you weren't careful that there could be some sort of weird mismatch of what code is running, versus what code is expected. So generally, they just default to saying the users gotta go to a whole new page, before the new experience comes up. But that can also be super annoying to a user, if they have thought they got something updated, and they have to go to a whole new page just to see that update.

They came to your page brand new a while back, but now they're back at your page, and they've loaded up your page, and nothing has changed from the last time they were there, until they click on the next link and now everything's changed again. And that's gonna look real weird to them.

So depending on your user experience that you want from a user when you're doing an update, you can actually tell your service worker to skip the waiting stage. There's a method that we will call in the installation in our service worker, that's called skipWaiting. My personal feeling is that I do this all the time, but I can certainly understand why you might wanna allow that sort of two-stage waiting, and then activation thing.

But I always like to skip the waiting stage in my usage of it. Which basically says, tell that old service worker as quickly as possible, kill yourself so that I can come into play. And it essentially almost immediately then, gets activated. Okay? But again the browser's gonna make sure in this life cycle that no two incidences of the service worker are actually active at any given moment.

So we might have a service worker in any one of these three stages, and it's only ever in one of these three stages. So we wanna grab which ever one that is. Now, if we're in this scenario where no service worker has been installed or a brand new one is just been installed.

In other words, we're not in the case where we've loaded the page, but it's the same service worker that it always was. The browser always checks for a new service worker every page load, it unconditionally checks for your new service worker. That used to be that the browser would pay attention to any like web caching headers that you may have sent with your service worker.

So the best practice was if you wanted that check, you had to make sure your service worker wasn't being cached in the browser cache. As of I think chrome 48 or something, they unconditionally skip the cache and force a reload check of the service worker similar to your favorite con, they checked the service worker every time.

So if you want to make an update to anybody, all you got to do is update your service worker, including like changing a comment or changing a version which we'll talk about in a moment when we get into it. So you gotta update your service worker, that will force a new service worker to load, install itself and we might wanna be notified that the new service worker has moved into that state, where it's now controlling things.

There's a controller change event that we wanna listen for.
>> Speaker 2: SW registration.
>> Kyle Simpson: swRegistration's what we called it up here at the top, that's our variable that we made.
>> Speaker 2: Okay.
>> Speaker 3: Are we redeclaring svcworker though on line-
>> Kyle Simpson: Yeah, we shouldn't be doing a var here, we should be assigning it.

Okay, we're gonna listen for the event on navigator.serviceWorker .addEventListener.
>> Kyle Simpson: Controllerchange, that means a new service worker had taken control of the page. It went through the installation, it's finished its waiting either normally or it forcibly quit its waiting. And now, it's ready to go, so onController.
>> Kyle Simpson: And if that's happened, then we definitely have a new service worker so we're gonna go ahead and reassign service worker, and now it's going to be the one that's at navigator.serviceWorker.controller.

>> Speaker 3: And you also have a typo on swRegistration.waiting. Just missing the t on ration.
>> Kyle Simpson: Sorry, thank you.
>> Kyle Simpson: I'm sure that's just the first of 5,000 typos I'm gonna make. There's a lot of typing here. We haven't even got to the service worker yet. One little tweak that I need to make here, is this isn't false.

This is the string none. I'm sorry about that.
>> Kyle Simpson: Okay, that should be all we need to do here to get our service worker up and going. So it is definitely a few more intricate steps than just saying new worker. But essentially, what we're doing is saying, go ahead and get my service worker up and going, get it installing itself.

And by the way, technically, you don't need to call register if you already have a service worker that hasn't changed. So technically, you could write some logic that only calls that, if you know that you've updated your service worker, once it's been registered, it doesn't ever have to be registered again unless it's changed.

So, you don't technically have to call this one. But I always call it every time. It's much simpler in the logic to just write this code. And it's essentially a no op, it's gonna check it regardless of whether you call register. So it's basically a no op in any other case, but it's a good idea just to make sure it's definitely there.

Cuz technically, I guess somebody could go in and on install your service worker, between visits on your page or something like that.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now