 Hello, everyone, and welcome back to the State of the Web. My guest is Jeff Posnick. He's on Google's Developer Relations Team. And today, we're talking about service workers and how they're elevating the capabilities of progressive web apps. Let's get started. All right, so Jeff, thanks for being here. In the context of web technologies, what does it mean for a worker? And what does it actually do? So the whole idea of a worker has been around for a while. Traditionally, there were web workers. And it basically serves as almost like a background thread for the web. So a worker can execute JavaScript code. That's kind of independent from the context of your actual web page. And it's a great way to kind of offload processing or do tasks that might take a certain amount of time without slowing down the main thread for your web page. And yeah, that's kind of been the traditional model for workers on the web. So now, what does it mean for a service worker? What does that actually do? The service worker's builds kind of on that concept and adds some superpowers, really things that you were not able to do before. So a service worker is similar to a worker in that it's running independent from your actual web page and it doesn't have access to things like the DOM or the global scope of your web page. But unlike workers, it could respond to specific events and some of those events relate to network traffic. So one of the really cool things and most common use cases for a service worker is to respond to outgoing network requests that your web page might be making. And you can kind of sit in between your web page and the network and almost serve as a proxy that you control. And you could write code to take advantage of things like the CacheStorage API and say, hey, I know how to respond to this particular request without having to go to the network. I could just use this CacheResponse and thereby saving the uncertainty and unreliability that comes with going against the network. It also enables capabilities like push notifications, et cetera. Yeah, so there's a whole bunch of kind of event-based listeners that you could set up in a service worker, including responding to push notifications that might come from a notification server and fetching requests and a few other kind of interesting things are kind of slated for the future as well. So what's the status of its implementation and support? Yeah, so service workers are well supported right now in modern browsers. So pretty much anything Chrome or Chromium based, Firefox, Safari and Edge at the moment. It's great. They all have at least the basic level of support for service workers and some of the enabling technologies like the CacheStorage API. So they're ready to use right now. So websites may experience network reliability issues at any given time. Would you recommend service workers for every website? Should they all be using one? Well, I mean, it's tempting to just throw a service worker up and see what happens. I would suggest to take a little bit more of a considered approach before adding a service worker to your web app. Ideally, a service worker will kind of play the same role that your web server would play and maybe share the same logic for doing routing and templating that your web server would normally respond with. And if you have a setup where your web server, for instance, for a lot of single page apps, the web servers just can respond with some static HTML that could be used to satisfy any sort of request, that's pretty easy to map into a service worker behavior. We call that the app shell model where the service worker will say, hey, you're navigating to XYZ URL, I could just respond with this HTML and it'll always work. So that's a really good model for using a service worker if you have a single page app. We're also seeing some success with partners who are using models where their servers implemented in JavaScript, they have some routing logic and they have some templating logic that's on JavaScript. And that translates over really well to the service worker as well, where the service worker can just basically fill the role that the server would normally play. I would say if you have a scenario where your backend web server is doing a whole bunch of complex templating and remote API calls and language that is not JavaScript, it really might be hard to get your service worker to behave exactly the same way. So in those scenarios, I mean, you can add a service worker and we have some kind of provisions in place to not pay the price of having that service worker intercepting all requests and then not doing anything and just going on against the network. There are ways of saying, hey, we have a service worker, but we're not gonna be able to respond with HTML for navigation requests. In those scenarios, it is still possible to use a service worker for things like, okay, show custom offline page when you detect that a user's network connection is down or implement a kind of interesting caching strategy like still while revalidate for certain types of resources. So it is still possible to add a service worker in those cases, but you won't necessarily get the same performance and reliability benefits that you get when your service worker really responds to all navigations with HTML. By essentially having a network proxy, juggling requests and responses, is there a latency cost to having a service worker? Yeah, so I mean, you're running JavaScript code that's sitting in between your web app and the network and that's not free. Some of it depends upon whether the service worker is already running. One of the kind of neat features about a service worker is that in particular to preserve battery on mobile devices, it's killed pretty aggressively. It doesn't just keep running forever in the background. So sometimes you do have to start up the service worker again and there is a cost involved in that startup. There's a really good talk from the Chrome Dev Summit that just happened a couple of months ago that kind of goes into some metrics and real world performance timings of exactly how long it takes to start up a service worker. Same tends to hundreds of milliseconds depending upon the actual device and things like the storage speed of the device. So you are gonna be paying that cost potentially when you're using a service worker. And again, that's really why it's important to make sure that you have a strategy in place for responding to requests, hopefully by avoiding the network and just going against cash storage API ideally. And if you're doing that, then you should see the service worker give you a net positive in terms of performance. Paying tens to maybe even hundreds of milliseconds is nothing compared to the multiple seconds of latency that you might expect from making a network request each time you navigate to a new URL. Right, what's the saying the fastest request is the one that you never need to make? Indeed, yeah. So what are some anti-patterns that you've seen the way that people have implemented service workers? There's a lot of power involved in using a service worker. It is just JavaScript that you could write that will pretty much do whatever you want. So you could do all sorts of crazy things, some of which are kind of cool as proof of concepts, but not necessarily things you want to deploy to production. In terms of the things that we've seen kind of as pain points are things that are pretty easy to unfortunately get wrong when implementing a service worker. I think one of the things that is most common is caching requests and responses as you go without having any sort of upper limit on the amount of data that you're storing. So you can imagine a website that maybe has a bunch of different articles. Each of those articles has images. It's pretty easy to write a service worker that just intercepts all those requests and takes the responses, saves them in the cache. But those cached responses will never get cleaned up by default. There's not really any provision in the Cache Store JPI for saying, you know, stop when you reach 50 or 100 entries or something like that. So you could very easily just keep using up space on your users' devices and potentially use up space for things that are never going to be used again. You know, if you have an article from a week ago and you're caching all the images in that article, that's kind of cool, I guess, if you're going to revisit an article immediately, but if it's a page that users never can go to again, then you're really just caching things for no reason. I would say that really one of the important things before you implement your service worker kind of have a strategy for each type of request and say, you know, here's my navigation requests that are being made for HTML, here's how I'm going to respond to them. Here are the image requests I'm making, you know, maybe it doesn't make sense to cache them at all or maybe only cache certain images and not others. So thinking about that and that really just means getting really comfortable with the kind of network info panel in the browser's dev tools and just seeing the full list of requests are being made. Sometimes your web app is making requests and you don't even realize it's happening because it's coming from third party code and your service worker ends up seeing that too. So you want to make sure that you know what your service worker is doing and you know what your web app is doing. And just one other, I would know that a lot of times and kind of pain point and things that could go wrong when using a service worker, it just has to do with controlling updates to resources. So, you know, you are stepping in between, you know, your web app and the web server, you're responding potentially to cache resources. If you're not sure that those cache resources are being updated every time you make changes to your actual website and you redeploy to your web server, it's possible that your users will end up seeing stale content kind of indefinitely. And this is a trade-off like seeing stale content but avoiding the network gives you performance benefits. So that's good for a lot of scenarios but you do need to have a provision in place for updating and making sure that, you know, maybe the user sees stale content then the next time they visit the site, they get fresh content. So, you know, you could do that right. Unfortunately, you could get that part wrong and the users can end up with a frustrating experience. So you maintain a tool called Workbox.js. What is that and what does it do? Sure, so Workbox is an open source set of libraries for dealing with service workers and kind of all aspects of building service workers. So we have some tools that integrate with build processes, including, you know, we have Webpack plugin, we have a command line tool, we have a node module. And that aspect of the tool is basically something that you could drop in your current build process and kind of get a list of all of the assets that are being produced every time you rebuild your site along with kind of some fingerprinting information. Like, you know, this is a particular version of your index.html. Workbox will keep track of that for you and then it will efficiently cache all of those files that are being created by your build process for you. And that just helps ensure that you don't run into scenarios like I just described where you've rebuilt your site and, you know, you never get updates to your previously cached resources. And we also have some tools as part of Workbox that kind of are more executed at runtime as part of the service worker. So some libraries are doing common things like routing requests. We have, there's just kind of some canonical response strategies for dealing with caching. So things like still while we're validated or going cache first, we have implementations of those strategies inside of Workbox. And then we have some kind of like value ads on top of what you get with the basic service worker spec and the cache storage spec. So we actually have an implementation of the cache expiration policy that you could apply to the caches that would otherwise just grow indefinitely. But using Workbox, you could say, hey, you know, I'd actually like to stop when I reach 10 items and, you know, purge the least recently used item in this cache when that happens. And a few other kind of random modules. We see it as a bit of a kind of grab bag for all the things that somebody might want to do with a service worker. And we kind of ship them as individual modules. You could choose the ones that you think would be useful for your particular use case. You don't want to use something, that's fine. You don't have to incur the cost of, you know, downloading it or anything like that. Do you foresee some of those caching and expiration policies making their way back into the cache storage API? Yeah, I mean, it's kind of interesting whenever you have something that's almost like a polyfill for some behavior on the web, you know, whether that ends up being implemented back into the standards and, you know, the actual runtime could just fade away and just use the underlying standards. And, you know, I'd like to see that. I think that Workbox has been really great for kind of enabling folks to ship service workers in production and seeing the types of things that they actually need when you're shipping something in production. And a lot of times when you could do that and you could point to something like, yeah, you know, it is actually important to have, you know, runtime cache expiration that can then be used, you know, when going to different standards groups and saying, hey, we really do need to extend, you know, what's supported natively in the platform to take care of this really common use case. You know, whether it actually happens or not, remains to be seen. But, you know, I think Workbox is positioned to help folks with kind of that initial proving that these things are necessary stage and we'll kind of take it from there. So in terms of adoption, according to the HTTP archive, less than 1% of websites tested actually include a service worker, which is kind of a misleading number for two reasons. The first is that it's actually growing at a very fast rate. And the websites that do include it are actually pretty popular websites. Can you give us some examples of those? Yeah, so I think, you know, the wrong number of URLs, unique URLs might be on the lower side, but I think in terms of traffic, you know, sites as big as Google search have deployed a service worker for some types of clients. You know, partners that we've talked about using, you know, Workbox in particular in the past include like Starbucks has a nice progressive web app that's implemented Pinterest as well. And there's also some sites that you might have heard of like Facebook and Twitter that are using service workers, not using Workbox, but using them to kind of unlock things like, you know, their progressive web app experience or, you know, in some cases just showing notifications, which is important part of, you know, being on the web and having parity with native apps. So, you know, I think that the actual number of, you know, visits to web pages is probably much higher than the 1% number would indicate. And, you know, I mean, there are challenges with adding a service worker into especially legacy sites. You know, it does take that coordination that we talked about before to making sure that your service worker actually is behaving in a similar way that your web server would behave. And, you know, that doesn't always fit into existing sites. So a lot of times what we've seen when working with partners in particular is like, you know, you're planning a rewrite, re-architecture of your site anyway. That's a great time to add a service worker in and just kind of take care of that story as well. Are there any options for CMS users who may be using things like WordPress or Drupal? So there definitely are. And I think that, you know, first of all, I'd refer everybody back to another talk from the most recent Chrome Dev Summit that really goes into some detail about the WordPress ecosystem in general. So they have a really cool solution. Some folks from the DevRel team at Google have been working on it. And I think it kind of works around one of that problem I was saying where the architecture for your kind of backend web server needs to match up with the service worker implementation. Like kind of just setting a baseline. So it's not an attempt to take any arbitrary WordPress site that might be out there, which might be executing random PHP code depending upon what kind of themes and extensions and all the other stuff is going on. You really are not going to be able to successfully translate that into just a general purpose service worker. But the approach that was described in this talk seems to be a building on top of kind of a common baseline of using the AMP plug-in as a starting point. So any site that has gone through the effort of kind of meeting all the requirements for using the AMP plug-in. So that means, I don't know the full set, but I think like not running external scripts, not doing anything too crazy with other plugins that's inserting random HTML on the page. Building on top of that, you can then have a service worker that's like, OK, I actually do know how to handle this subset of activities that WordPress is doing when it's using the AMP plug-in. And it can automatically generate that service worker for you. So again, it's part of a migration story. I think it's not going to just drop into any existing legacy WordPress site, but it does give a nice path forward for folks who are planning on rewriting anyway or planning on making some changes anyway. Yeah. And plugging into the CMS ecosystem is a great way to increase adoption by tens of percent on the web. Yeah, absolutely. So what kinds of resources would you recommend for someone who's just getting started with service workers? We have a lot of material available, some of which is more recent than others. I would say that the things that I have worked on most recently are the resiliency section of web.dev. So if you were to go there, kind of have something that will walk you through the various steps of thinking about adding a service worker to your website, or just really thinking about making your website more resilient in general. So it'll talk about identifying your network traffic. It'll talk about using the browser's HTTP cache effectively, which is kind of your first line of defense. And then it'll kind of go into how you could add Workbox to an existing site and the various steps involved there. So if you want kind of a guided path, I would say that's one option. We'll biased for that. I would say that if you want to just learn more about service workers in general, then material written by my colleague Jake Archibald is probably the best bet for folks who really want a deep dive on things. He was somebody who worked on the actual service worker specification. And he knows more than anybody else about these things. So he has a really great article talking about the service worker lifecycle, just all the different events that get fired and how you have to handle those events differently and the implications that they have for the state of your caches and updates and things like that. So diving into that would be kind of my recommended starting point. And he has another article that talks about a cookbook almost for recipes, for caching. So implementations of the still while we validate pattern, cache first pattern. If you wanted to implement it yourself instead of using Workbox, he kind of walks through the process there. Is that the offline cookbook? Yeah, it's the offline cookbook. And if you want something that's really offline, there's some actual physical books that are pretty cool related to service workers and progressive web apps in general. There's a new book written by Jason Grisby in particular that I would recommend and just kind of talks a little bit about not necessarily some of the technical aspects of service workers, but more about why you should think about adding a service worker to your site and why you might want to build a progressive web app in general. And that's a really cool book that kind of takes it from a slightly different angle, but gives some good perspective. Great, Jeff, thank you again for being here. Absolutely. You can find links to everything we talked about in the description below. Thanks a lot and we'll see you next time.