Skip to content

Instantly share code, notes, and snippets.

@anthonyalvarez
Last active September 28, 2018 17:08
Show Gist options
  • Select an option

  • Save anthonyalvarez/efe25e8ad92c8181de477ae45179bf4c to your computer and use it in GitHub Desktop.

Select an option

Save anthonyalvarez/efe25e8ad92c8181de477ae45179bf4c to your computer and use it in GitHub Desktop.
Service Worker

Service Workers

Feature Probe

with error handling.

This is the entry point that starts entire process of an offline web experience. Browser has to support serviceWorker object.

if ('serviceWorker' in navigator) {

  navigator.serviceWorker
    .register('./sw.js', { scope: './' })
    .then(function(registration) {
      console.log('[Service Worker Registation]', registration.scope);
    })
    .catch(function(error) {
      console.log('[Service Worker Registation] Failed to Register', error);
    })

}

Events

serviceWorker object is event driven. Event listeners below are usually in the same file. For example: sw.js file.

Install

/**
 * @description Installs service worker for the first time, give it a name and populates it with cache date.
 * @param {object} event
 * @returns none - Installed Service worker
 */

self.addEventListener('install', function(evt) {
  let FUCNTION_ID = ' id #1 ';
  let FUCNTION_DESC = 'Install event';
  console.log(CONSOLE_LOG_ID + FUCNTION_ID + FUCNTION_DESC);
  evt.waitUntil(precache());
});

Precache website static files

function precache() {
  let FUCNTION_ID = ' id #2 ';
  let FUCNTION_DESC = 'Precache to cache name';
  console.log(CONSOLE_LOG_ID + FUCNTION_ID + FUCNTION_DESC, CACHE_NAME);
  return caches.open(CACHE_NAME).then(function (cache) {
    return cache.addAll(URLS_TO_CACHE);
  });
}

Activatation

/**
 * @description Service worker is activating at this point and deletes old caches.
 * @param  {object} e
 * @returns none - Activated Service worker
 */

self.addEventListener('activate', e => {
  let FUCNTION_ID = ' id #3 ';
  let FUCNTION_DESC = 'Activate Event to cache name';
  e.waitUntil(
    caches.keys().then(keyList => {
      return Promise.all(keyList.map(key => {
        if (key !== CACHE_NAME) return caches.delete(key);
      }));
    }));
  // return self.clients.claim();
  console.log(CONSOLE_LOG_ID + FUCNTION_ID + FUCNTION_DESC, CACHE_NAME);
});

Fetch

/**
 * @description Intercepts all fetch requests. It will then respond with the cached response if one is found, if not it will fetch the data from network using the fetch API.
 * @param {object} event
 * @returns {object} event.request - Resource from cache or network
 */
 
self.addEventListener('fetch', function(event) {
  event.respondWith(
    caches.match(event.request)
      .then(function(response) {
        if (response) {
          return response;     // if valid response is found in cache return it
        } else {
          return fetch(event.request)     //fetch from internet
            .then(function(res) {
              return caches.open(CACHE_DYNAMIC_NAME)
                .then(function(cache) {
                  cache.put(event.request.url, res.clone());    //save the response for future
                  return res;   // return the fetched data
                })
            })
            .catch(function(err) {       // fallback mechanism
              return caches.open(CACHE_CONTAINING_ERROR_MESSAGES)
                .then(function(cache) {
                  return cache.match('/offline.html');
                });
            });
        }
      })
  );
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment