Service Workers 
Tags: react, javascript, webdev, serviceworker
Published: 2019-05-08 16:33:40

---
title: Service Workers 
published: true
description: A semi-complete guide to service workers along with basic setup in a react application.
tags: #react #javascript #webdev #serviceworker
---


### Summary

I will be going over Service Workers at a very high level in this post. Later on I will discuss how you could implement a service worker into your React application. At the bottom there will be links to all my sources and documentation so you can learn more!

### What is a Service Worker?

* "A service worker is a script that your browser runs in the background, separate from a web page, opening the door to features that don't need a web page or user interaction.” – [Matt Gaunt](https://developers.google.com/web/fundamentals/primers/service-workers/)
* JavaScript code that executes on page load.
* Gives developers much more control of the browser. 

#### Service Worker Lifecycle
<img src ="https://developers.google.com/web/fundamentals/primers/service-workers/images/sw-lifecycle.png" width=400px />

### Why should we use it?

* Required for a Progressive Web App
* Provide offline website support
* Can make your site have a heartbeat by watching for site updates and even auto update!
  * This can include things like forcing a user to utilize a new build when pushed out, or just notifying them there is an update.
* If no offline support needed it speeds up site revisits by caching the site code.
* Significantly lowers your deployment downtime. 
* Your users are running the site on their local copy and aren't relying on the server, even when clicking links and navigating around your site.

#### Website screenshot reference, We are serving some high sized images directly from our server.

<img src ="https://imgur.com/qdcTptT.png" width=500px />

Download size & load times __without__ a service worker

<img src ="https://imgur.com/pj2vkYt.png" width=700px />

Download size & load times __with__ a service worker

<img src ="https://imgur.com/qG4GEE1.png" width=700px />

As you can see there is a huge difference in load times and bandwidth utilization! We only have to download the images once when the service worker is utilized vs every page load when it doesn't exist. Now of course you could throw the images on a seperate image hosting platform like the one I'm using for the images above, but that might be against security standards for your app. Also images aren't a great example, but imagine your application is very large scale and you have a lot of code that needs to be served up. Your browser won't be able to auto-cache that and you can't access it offline.

### Think about mobile!

The image below is from A [tomsguide](https://www.tomsguide.com/us/best-mobile-network,review-2942.html) article that talks about mobile network speeds.

<img src ="https://img.purch.com/fastestcarriers-2018-main-chart-v2-4-jpg/o/aHR0cDovL21lZGlhLmJlc3RvZm1pY3JvLmNvbS9BL08vODA1MjAwL29yaWdpbmFsL0Zhc3Rlc3RDYXJyaWVyc18yMDE4LW1haW4tY2hhcnRfdjIuNC5qcGc=" width=600px />

Sure those seem pretty quick, but these are best case scenerios. The article goes on to talk about this as they only tested "...wireless network speeds at multiple locations in eight U.S. cities in the past year...". _With service workers your users will be able to revisit your application much faster even while using slower interent speeds._

#### in addition to mobile...

Have you ever been in a coffee shop to spin up your favorite website and it took forever? It could be possible that your favorite site isn't implementing any sort of caching. Because of this while you are sipping your favorite drink you can't browse the site you wanted to browse! Unfortunatley you probably won't be able to get a hold of their dev team and show them this article.

At that coffee shop you were probably on your laptop which should be faster than your phone, right? Well... not necessarily. Most coffee shops have lower tier data plans and it shares with everyone in the building (even employees and shop devices).

Here is a graph by [speedtest.net](https://www.speedtest.net/insights/blog/2018-internet-speeds-global/) that shows global internet speeds. This really shows that you have to think about network speed and users coming back to your application. You don't want everyone taking 3 seconds to load your page every time (maybe longer, maybe shorter).

<img src ="https://www.speedtest.net/insights/blog/content/images/2018/12/Graphic-Tables-Final-v2_fixed-average.png" width=500px />

### I'm in! How do I get started?

If you are using React then this is going to be a piece of cake! If you aren't using React I recommend heading [here](https://developers.google.com/web/fundamentals/primers/service-workers/registration) to learn more about how you can register your own service worker. 

My recommendation is to utilize the package [offline-plugin](https://github.com/NekR/offline-plugin) due to the versatility and options it provides. You could totally use the one that comes with [Create-React-App](https://github.com/facebook/create-react-app)(CRA) if you wanted to, but you will miss out on a lot of functionality. What's built into CRA is a good start for sure, especially if you aren't interested in any of the options offline-plugin provides.

#### Basic service worker implementation via CRA.

This snippet is located in your `src/index.js` file by default!
```js
import * as serviceWorker from "./serviceWorker";

// ...

serviceWorker.register();
```

#### offline-plugin implementation

You've made it this far so I'm going to make it nice and easy for you. Follow these steps if you are wanting a service worker with auto updating functionality.

1. `npm i offline-plugin react-app-rewired --save-dev` in your project directory.
2. Go to your projects root directory (where your package.json is located) and create a new file called `config-overrides.js`.
3. In that file paste the following

```js
// This is a good baseline for setting up auto install
const OfflinePlugin = require("offline-plugin");

module.exports = function override(config, env) {
  if (!config.plugins) {
    config.plugins = [];
  }
  config.plugins.push(
    new OfflinePlugin({
      autoUpdate: true, // true = check every hour for an update while user is connected to your application.
      ServiceWorker: {
        events: true
      }
    })
  );
  return config;
};
```

4. From here you have to decide if you want to alert or enforce the user to update when you push a new verion. If yes... continue! If no then you are done! :tada:

5. Let's give the user an option to update! In a new component that gets mounted on site visit let's add some code!

```js
import React, { Component } from "react";
import runtime from "offline-plugin/runtime";

class Updater extends Component {
  state = {
    updateSite: false,
    updating: false
  };

  componentDidMount() {
    // You can test on local development my remove or changing this if
    if (process.env.NODE_ENV === "production") { 
      runtime.install({
        onUpdateReady: () => {
          this.setState({ updateSite: true });
        }
      });
    }
  }
  
  applySomeUpdate = () => {
    runtime.applyUpdate();
    setTimeout(() => {
      window.location.reload(true);
    }, 1000); // Give some time for the new service worker to start after the update
  };
  
  render() {
    return (
      <div>
        {this.state.updateSite ? (
          <button onClick={this.applySomeUpdate}>Update now!</button>
        ) : null}
      </div>
    );
  }
}

export default Updater;
```

6. Boom! 💥 Well kind of... You should definitly style this and make it your own! 

You now have a very rough example of a component that will show a button when a new service worker is ready to be installed. This will run everytime someone visits your site. The best part is that a check for a new service worker costs nothing! 0 bytes and 0 lag!

### Conclusion

You've made it to the end and hopefully with a better understanding of service workers and why they are so great. I (and now you) have barely grazed the surface of service workers. With the limited understanding we both have, we can all push for a better web. Making our applications faster and more accessable together.

Now get out there and hire some Service Workers!

Thank you! 🙏 

### References

[service-worker docs](https://developers.google.com/web/fundamentals/primers/service-workers/)

[mobile network speed](https://www.tomsguide.com/us/best-mobile-network,review-2942.html)

[speedtest](https://www.speedtest.net/insights/blog/2018-internet-speeds-global/)

---

[service-worker registration](https://developers.google.com/web/fundamentals/primers/service-workers/registration)

[Create-React-App](https://github.com/facebook/create-react-app)

[offline-plugin](https://github.com/NekR/offline-plugin)

[react-app-rewired](https://github.com/timarney/react-app-rewired)

---

Originally posted here https://www.crema.us/blog/a-complete-guide-to-service-workers