Codementor Events

Understanding The Service Worker LifeCycle

Published Jun 12, 2018Last updated Dec 09, 2018
Understanding The Service Worker LifeCycle

The desired user experience on the web is to access information without interruptions. Unfortunately, even with high speed connectivity, we still experience delays.

Let me explain briefly: to get the information we need on our screen, we send requests over the network and wait for that response. But, what if, the network is busy, there is a misconfigured proxy somewhere, or you can't access the internet for whatever reason? It could be anything, really, and we have to wait for a very long time.

This can be frustrating for most users.

But there is a solution: building Offline First web apps.

How can we achieve an offline experience on the web?

To achieve offline experience, we need to take care of:

  1. Caching Assets. The browser stores static assets such as HTML, CSS, images, etc., such that when needed next,they are fetched from the browser cache. Big deal when the network fails.
  2. Storing data on the client side. HTML5 came bearing good news with offline technologies, such as Web Storage, indexed databases among others, enabling you store data locally on the user's device.
Application Cache

Application Cache (warning: It is being deprecated) tried resolving the caching by allowing you to specify the set of resources you'd like the browser to cache and enjoy offline browsing, 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.)

Useful when the user is disconnected from the network, but did it deliver its promise? Read API is A douchbag.

Service workers

Service worker is a script (JavaScript file), that the browser runs in the background, acting like a proxy between application and the network.

Service worker enables applications, intercepts requests, and then modifies responses, caches those requests to improve performance, and provides offline access to cached data, which makes it reliable.

Service worker is a type of web worker. It runs on a separate thread from the web pages and UI, enabling them to work without an active browser session.

It has no access to DOM. Instead, it communicates with the pages through post message. Those pages can then manipulate DOM if needed.

It offers you complete control over your app behavior, especially when network is unavailable or slow.

This kind of control is the reason service workers run only on HTTPS,to avoid man in the middle attacks, though an exception for local requests is not necessary during development.

  • The intended use is to create offline first experiences
  • Intercept network requests and handle response based on network availability
  • Great benefits online when experiencing slow connection
  • Allow access to push notification and background sync

Service workers let you handle network requests differently from caching. Service worker revolves around recent WebAPI

  1. Fetch. A fetch event is fired when resources are requested over the network. Perform standard request offers the ability to look in the cache before making network requests. Inside a service worker allows for intercepting requests and modifying the content other than the object requested. Use respondWith() to tell the browser we will handle the requests.
  2. Cache API. Cache API is independent from network status or browser cache. It gives you control on how and when to cache. It will not update items in the cache unless explicitly requested. Items in cache do not expire, they are gone when you delete the old cache.

Service worker lifecycle

  • Registration
  • Install
  • Activate
Registration

To use a service worker, you must register and define its scope.

Registration will tell a browser the location of the service worker and start installing it on the background.

Code to register Service worker placed in sw.js

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.

Browser Support

Since some browsers don't support service workers yet, Is Service Worker Ready, perform a feature check by wrapping the service worker in an if statement.

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

Scope

The scope defines the pages that a service worker controls. The default scope is defined by the location of a service worker script. This means if you register a service worker at the root folder, it is not necessary to define its scope because it controls all of the pages.

navigator.serviceworker.register('/sw.js', { scope: '/'
});

The browser wont re-register an existing service worker on call, but return a promise for existing registration.

Installation

Once the browser has registered the service worker, it is immediately downloaded. If the browser considers a service worker new, either:

  1. The service worker has never been registered before
  2. You altered the service worker script and there are byte differences

install event is fired.

This is a perfect opportunity to fetch for resources that make the application shell from the network and cache them. It's deal for the static resources that our site depends on, such as HTML, CSS, Fonts, JavaScript, etc.

If there is a previous version of service worker 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, it becomes the next version in waiting.

To delay the installation process and determine its success, we pass a promise to event.waitUntill method.

If the promise resolves, the browser knows the installation has completed. If it fails, well then, it is discarded. No cause for alarm because the previous version of the service worker is still working.

This ensures only one version of your script is running at any given time.

self.addEventListener('install', function(event) { event.waitUntil( ); });
Activation

Once a service worker has successfully completed the installation phase, it enters activation stage.

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. However, it cannot control pages that were already loaded. To control the already loaded pages, a reload is required.

In the case where the service worker is updated, (not the browser's first time interacting with a service worker), the newly installed service worker cannot take control until all of the pages the previously installed service worker are closed.

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

You can take control of of uncontrolled pages by calling clients.claim() within your service worker once it's 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 reload won't help much because we are 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, it's 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 are also effective during slow connectivity online
  2. Service workers are programmable JavaScript "servants/workers"
  3. They can not access DOM directly. Instead, it communicates with the pages it controls through responding to messages via postmessage.
  4. Requires sites to be served over HTTPS. This is important because they intercept requests and can modify 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. If I missed something, please let me know by commenting below.

Connect with me on Twitter

Discover and read more posts from Cindy Achieng
get started
post commentsBe the first to share your opinion
Show more replies