DEV Community

Trevor
Trevor

Posted on

Service Workers

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
  • JavaScript code that executes on page load.
  • Gives developers much more control of the browser.

Service Worker Lifecycle

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.

Download size & load times without a service worker

Download size & load times with a service worker

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 article that talks about mobile network speeds.

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 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).

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 to learn more about how you can register your own service worker.

My recommendation is to utilize the package offline-plugin due to the versatility and options it provides. You could totally use the one that comes with 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!

import * as serviceWorker from "./serviceWorker";

// ...

serviceWorker.register();
Enter fullscreen mode Exit fullscreen mode

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
// 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;
};
Enter fullscreen mode Exit fullscreen mode
  1. 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! 🎉

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

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;
Enter fullscreen mode Exit fullscreen mode
  1. 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

mobile network speed

speedtest


service-worker registration

Create-React-App

offline-plugin

react-app-rewired


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

Top comments (2)

Collapse
 
tbrixey profile image
Trevor

Thanks for the trick! This my first ever blog post so things like this are super helpful!

I thought about making a module approach, but wasn't sure if it would be 100% worth it. Maybe that'll be the next step to this so I can learn how to publish to npm and all that jazz.

 
tbrixey profile image
Trevor

Sweet. Thanks for this info. This will definitely be something I look into in the near future.