Understanding The Service Worker LifeCycle

an image showing service worker life cycle

https://dev.to/

published on: | by cindy In category: Web Development Tools

The desired user experience on the web is to access information without interruptions. Unfortunately, even with high-speed connectivity we still experience some delays. Let me explain briefly. To get the information we need on our screen, we send requests over the network and wait for the response. But what if the destination server is busy or has a bug? or there is a misconfigured proxy somewhere, or you can't access the internet for whatever reason? It could be anything really, and you have to wait for a very long time for the response, if you even get the response? This can be frustrating for most users.

How can we achieve offline experience on the web?

For a long time, developers had no control over these requests. You make a request and wait for the response from the server which may return a response or not or maybe fast or even slow. The solution is building apps that work great regardless of network availability. To achieve offline experience on the web, we need to take care of two things.

  1. Caching. The browser stores static assets such as HTML, CSS, images e.t.c such that when needed next, they are fetched from the browser cache.A big deal when the network fails.
  2. Storing data on the client side Html 5 came bearing good news with offline technologies such as Web Storage, indexed databases among others enabling you to store data locally on the users' device.

A little history on offline web browsing

Application Cache (Warning: It is being deprecated) achieved offline browsing on the web. Developers specified the set of resources for the browser to cache and enjoy offline browsing. It had many benefits including Improved speed by caching resources locally( no need for network trips), and reduced server load (the browser only downloads resources that have changed from the server.)

But did it deliver its promise effectively? Yes and No. Yes because it did allow for offline browsing.No because Application Cache didn't express clear intent in the manifest and was easily caught by unexpected behavior read API is A douchbag Service Worker, the relatively new kid was born.

Serice worker

Service worker is simply a javascript file that sits between you and network requests. It is a type of web worker meaning it runs separately on its thread on the background.It has no access to DOM or web pages, instead Communicates with the pages it controls through post message. Service worker allows you to intercept requests and modify the response. As a developer, you have complete control on how to handle requests. Based on network availability, you could send the request to the network, as usual, skip the network and get the response from a cache, or even create a custom response.

Service worker lives longer than the web pages it control and susceptible to manipulation. The worker runs only on https to avoid man in the middle attacks. However, an exception to this is allowed during development on localhost.

Benefits of Service worker

  1. The intended use is to create offline first apps.

  2. Offline first apps offer great user experience for everyone regardless of connectivity. Content is delivered first before sending requests to the network.

  3. Let me say something about online first.As the name suggests we have to fetch content from the network then maybe fallback to cache or display an error page. This approach is perfect for cases of good connectivity and works for offline as well. But it has one major fault: Terrible for Lie-fi(slow connectivity).Remember we have to wait for the network response.
  4. Great benefits online when experiencing slow connection. The performance speed is increased by reducing network requests for certain assets.
  5. Users get a customized offline fallback experience because service worker has the ability to Intercept network requests and handle response based on network availability.

Registering service worker and scope

To use a service worker script, you tell the browser where to find it by registering the script. Register the script with the sample code below:

navigator.serviceWorker.register('/sw.js').then(function() {
    console.log('Registration worked!');
}).catch(function() {
    console.log('Registration failed!');
});
};

A Service Worker returns a promise. If the Promise resolves, the registration is successful otherwise the registration of the new service worker failed.

Note

The browser won't re-register an existing service worker on call but return a promise for an existing registration

Scope

The scope defines the pages that a service worker controls. The service worker will control any page whose url begins with the scope.

For example: scope: '/src/' // will control deeper Url and wont control shallow Url. /src/home/ // will be controlled since its a deeper url /src // won't be controlled since it is considered a shallow url because no trailing slash) /public/ //will not be controlled because it is unrelated url

The default scope is determined by the location of the service worker script i.e the path where the script is. In most cases, you don't have to give the sw a scope simply put it in the right path

You can register multiple service workers with different scopes if the projects share the same origin Browser Support

Use is service worker readyto check for browser support.Since some browsers don't support service workers yet so to be safe perform a feature check by wrapping the service worker in an if statement.

(!navigator.serviceWorker) return;
navigator.serviceWorker.register('/ sw.js ').then(function() {
    console.log('Registration worked!');
}).catch(function() {
    console.log(''
        Registration failed!');
});
};

Service worker lifecycle

Installation

Once the browser has registered the service worker, it downloads the script in the background and then attempts installation. An install event is fired if the browser considers the service worker to be ''new ''. The browser considers the service worker new if:

  1. The Service Worker has never been registered before and its the browser first encounter with the script
  2. The browser detects even a byte difference between the previously installed and the new service worker

In the case where a previous version of the service worker is already running, it will still continue to serve pages. The browser won't let the new service worker take control until the installation phase is complete. Instead, the new service worker becomes the next version in waiting.To determine its success, we pass a promise to event.waitUntill method to delay the installation phase to ensure that only one version of service worker script is running at any given time.

If the promise resolves, the browser knows the Installation has completed otherwise it has failed and can be discarded. No cause of alarm because even if the promise fails to resolve, the previous version of the service worker is still working.

This is a perfect opportunity to fetch for resources that make the application shell from the network and cache them. Ideal for the static resources that our site depends on such as Html, CSS, Fonts, Javascript, etc.

Activation

Once a service worker has successfully installed, it enters the activation stage. However, service worker cannot control pages that were already loaded because of the simple fact that Service Worker script can only control pages as they load.

In the case of the browser first encounter with a Service Worker, the service worker becomes active upon successfully completing the installation phase and will be able to control new page loads. To control the already loaded pages, a reload is required.

In the case where the service worker is updated, (Not the browser first-time interaction with a service worker ), for the newly installed service worker to take control, close all the pages loaded with the previous service worker.

Once all pages using the old (previously installed) service worker are gone, the new one activates, firing an activate event.

service worker can take control of of uncontrolled pages by calling clients.claim() within your service worker once its activated

self.addEventListener(''activate'', function(event){
  });

Since the previous version is out of the way, it is a perfect time to delete the old cache so that all users can have the current version of our site.

gotcha

We change files all the time! When we make changes in our file say a css file, this can become a ''problem''.A page reloads won't help much because we still using the cache with the old css.

Despite the changes in our css file, our site remains the same. Meaning, to see the changes, we make a change to the service worker script, you can simply add a comment, remember its just a byte difference and the browser will consider it as ''new''

Notes

  1. Service workers do not provide cached data for offline use only, but also effective during slow connectivity online.
  2. Service workers are programmable JavaScript "servants/workers"
  3. They can not access DOM directly, instead, communicate with the pages it controls through responding to messages via postmessage.
  4. Require sites to be served over https. This is important because they intercept the request and can modify the response, to avoid hijacking by third parties
  5. Stays idle when not in use, restarted when next needed
  6. Make extensive use of promises

Further reading

  1. Introduction to service workes
  2. Jake Archibald

Conclusion

Thank you for reading, hope you are ready to give users an amazing experience both online and offline. Tell me if you find this article useful or if I missed something, please let me know by commenting below.

Connect with me on twitter