Understanding The Service worker LifeCycle
Tags: serviceworkers, progressivewebapps, offlinefirst, cacheapi
Published: 2018-05-17 16:11:10

---
title: Understanding The Service worker LifeCycle
published: true
tags: service workers, progressive Web Apps, Offline-First, CacheAPI 
canonical_url: 
---

The desired user experience  is to access information on the internet 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, just what if the network is busy, or  there is a mis-configured 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 <code>Offline First</code> web Apps.
##### But How Do achieve Offline Experience ?
To achieve offline experience we need to take care of:

1. **Caching Assets**. The browser stores static assets such as html,css,Images.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**.Html 5 came bearing good news with offline technologies such as Web Storage, indexed databases among others enabling you store data locally on the users device.<a href="https://www.html5rocks.com/en/features/storage" target='_blank'></a>

##### Application Cache
<a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Using_the_application_cache" target="_target"> Application Cache</a> (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  <code>locally</code>( 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 <a href="http://alistapart.com/article/application-cache-is-a-douchebag" target="_blank">API is A douchbag</a>

### 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 enable applications  intercept  requests and then modify response,cache those requests to improve performance and provide offline access to cached data which makes it reliable.

Service worker is a type of  <a href="https://html.spec.whatwg.org/multipage/workers.html">web worker</a>,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 Communicates with the  pages through <code>post message</code> ,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-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 resource is requested over the network. Perform standard request i.e Offers us the ability to look in the cache before making network requests.Inside a service worker,allows for intercepting  requests and then modify the content other than the object requested.Use <code>respondWith()</code> 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 <code>sw.js</code>

```javascript
    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 <a href="https://jakearchibald.github.io/isserviceworkerready/"  target="_blank">Is Service Worker Ready</a>,perform a feature check   by wrapping the service worker in an <code>if statement</code> .
<pre><code class = 'javascript'>if (!navigator.serviceWorker) return;
navigator.serviceWorker.register('/sw.js').then(function() {
    console.log('Registration worked!');
}).catch(function() {
    console.log('Registration failed!');
});
};</code></pre>
**Scope** 
 
The scope define 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 the pages.
<pre><code class = 'javascript'>navigator.serviceworker.register('/sw.js', {
    scope: '/'
});</code></pre>
    
> 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 <code>downloaded</code>  if the browser considers a  service worker new either by

1. The Service Worker  has never been registered before. or
2. You altered the Service Worker Script,byte differences.

 <code>install event</code> is fired.

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.

If there is a previous version of service worker already running,  it will still continue to serve pages.
The browser wont 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 <code>event.waitUntill</code> method. 

If the promise resolves,the browser knows the Installation has completed.If it fails,well then it is discarded.No cause of  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.
<pre><code>self.addEventListener('install', function(event) {
  event.waitUntil(
     );
   }); </code></pre>

##### 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 first time interacting with a service worker ), the newly installed service worker cannot take control until all 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 <code>clients.claim()</code> within your service worker once its activated

<pre><code class='javascript'>self.addEventListener('activate', function(event){
});</code></pre>

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  wont help much  because we still using the cache with the old css.

Despite the changes in our css file,our site remain 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 does 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 <code>postmessage</code>.
4. Require sites to be served over https. This is important because they intercepts request 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. <a href="https://developers.google.com/web/ilt/pwa/introduction-to-service-worker">Introduction to service workes</a>

2. <a href="https://developers.google.com/web/fundamentals/primers/service-workers/lifecycle"> Jake Archibald</a>

### Conclusion
Thank you for reading, hope you are ready to give users an amazing experience both online and offline.Let me know if liked the article or if I missed something!

<a href="https://twitter.com/achiengcindy1"> Connect with me on twitter</a>