Anirudh Modi
Full-Stack Javascript developer, you can follow me on : GitHub - https://github.com/anirudh-modi Medium - https://medium.com/@anirudh.modi2 Email - anirudh.modi2@gmail.com
More than just killing the mighty T-REX
Not everyone will run your app on Google Fiber!
Not everyone owns the fastest hardware!
Lesser dropping of users!
Users are lazy and there time is too precious!
App like feel!
Push notification API to keep the user engaging!
App deployment becomes
Dayyyyuuuummm !!!!
Offline support!!
A web app which
Slides for app shell
The benefits of an app shell architecture with a service worker include:
The app shell should ideally:
Add to home screen
Add a splash screen
Customize the Icon
What exactly is it?
The web app manifest is a simple JSON file that gives us the ability to control how our app appears to the user in areas where they would expect to see apps (for example, a mobile device's home screen), direct what the user can launch, and define its appearance at launch.
Creating a manifest file and linking it to your page is a straightforward process.
Control what the user sees when launching from the home screen.
This includes things like a splash screen, theme colors, and even the URL that's opened.
"display":"standalone"
"display":"browser"
"display":"fullscreen"
"theme_color":"#2196F3"
"start_url": "/?utm_source=homescreen"
{ "name": "HackerWeb", "short_name": "HW", "start_url": ".", "display": "standalone", "background_color": "#fff", "description": "A simply readable Hacker News app.", "icons": [{ "src": "images/touch/homescreen48.png", "sizes": "48x48", "type": "image/png" }, { "src": "images/touch/homescreen72.png", "sizes": "72x72", "type": "image/png" }, { "src": "images/touch/homescreen192.png", "sizes": "192x192", "type": "image/png" }], "related_applications": [{ "platform": "web" }, { "platform": "play", "url": "https://play.google.com/store/apps/details?id=cheeaun.hackerweb" }] }
<link rel="manifest" href="/manifest.json">
And finally, It opens the door to compete with Native apps.
// It is better to do which the feature detection so that
// our code doesn't start to throw error
if ('serviceWorker' in navigator)
{
// Path to your service worker file and also
// the default scope of your service worker
navigator.serviceWorker.register('./serviceWorker.js')
.then(function(ServiceWorkerRegistration)
{
// Returns the ServiceWorkerRegistration object
// Which holds the service workers which can either be
// installing phase, waiting phase or Active phase
console.log('Successfully registered service worker');
})
.catch(function(err)
{
console.warn('Error whilst registering service worker', err);
});
}
// The Service worker can lie in root directory
// but the scope can be all the files under the 'dogs'
navigator.serviceWorker.register('./serviceWorker.js', {'scope':'/dogs/'})
.then(function(reg)
{
console.log('Successfully registered service worker');
})
.catch(function(err)
{
console.warn('Error whilst registering service worker', err);
});
On re-registering the browser will detect a service worker already installed and it won't go through the process of registering/installing the same service worker again.
//sw.js
// This is the place where we will cache
// the files required for offline
addEventListener('install',function(event)
{
console.log('Installing service worker');
});
//sw.js
var cacheName = 'v1';
addEventListener('install',function(event)
{
console.log('Installing service worker '+cacheName);
// This says that the 'install' event needs to
// be extended until the process of caching
// our file or any other activity we desire to do
// is done or fails.
event.waitUntil(
caches
.open(cacheName)
.then(function(cache)
{
return cache.addAll(arrayOfFileToCache);
})
);
});
//sw.js
// Installing SW code
// This event is fired the moment installation phase
// of the service worker is over and the service worker
// becomes active ready to handle and intercept request
//
// This is also the place where we would clear our cached
// file from previous service worker
addEventListener('activate',function(event)
{
});
//sw.js
// We would again wrap the process of deleting old cache
// within 'waitUntil' so that we can montior
// if the process of deleting old cache
// was successful or not
addEventListener('activate',function(event)
{
var cacheWhitelist = [cacheName];
event.waitUntil
(
caches.keys()
.then(function(cacheNames)
{
return Promise.all
(
cacheNames
.map(function(cacheName)
{
if(cacheWhitelist.indexOf(cacheName) === -1)
{
return caches.delete(cacheName);
}
})
);
})
);
});
Considered updated if the service worker file is a byte-different
I have changed my service worker but it is still showing previous!
This is because by default only one service worker can be activated, and the new service worker is in waiting phase.
//sw.js
var cacheName = 'v1';
addEventListener('install',function(event)
{
console.log('Installing service worker '+cacheName);
// This says that the 'install' event needs to
// be extended until the process of caching
// our file or any other activity we desire to do
// is done or fails.
event.waitUntil(
caches
.open(cacheName)
.then(function(cache)
{
return cache.addAll(arrayOfFileToCache)
.then(function()
{
// This signifys that the new worker will instantly
// replace the old service worker, once the new files
// are cached
self.skipWaiting();
});
})
);
});
Note: If using then our files are mismatch and it becomes mandatory to either forcefully refresh the browser or convey this message to the user
// All the request lying within the scope of the service
// worker will be handled within the fetch event
addEventListener('fetch',function(event)
{
event.respondWith
(
// Find within the cache if the url being requested is present or not
caches.match(event.request)
.then(function(response)
{
// If the resource being requested was found in cache we respond
// with the cache result
if (response)
{
// retrieve from cache
return response;
}
// Else we use the fetch API using the request
// to contact to the network
// for the desired file
return fetch(event.request);
})
);
});
Lighthouse tests if your app:
Lighthouse is available as a Chrome extension for Chrome 52 (and later), and in Chrome dev tools for Chrome 60 (and later).
https://gist.github.com/Rich-Harris/fd6c3c73e6e707e312d7c5d7d0f3b2f
https://www.youtube.com/watch?v=RWLzUnESylc
http://blog.gaborcselle.com/2012/10/every-step-costs-you-20-of-users.html
https://developers.google.com/web/fundamentals/instant-and-offline/service-worker/lifecycle
https://jakearchibald.com/2014/offline-cookbook/
https://developers.google.com/web/fundamentals/getting-started/primers/service-workers
https://addyosmani.com/blog/getting-started-with-progressive-web-apps/
https://developers.google.com/web/ilt/pwa/
https://www.youtube.com/watch?v=cmGr0RszHc8&feature=youtu.be
https://www.youtube.com/watch?v=3Tr-scf7trE&list=WL&index=91
https://www.youtube.com/watch?v=J2dOTKBoTL4
By Anirudh Modi
Full-Stack Javascript developer, you can follow me on : GitHub - https://github.com/anirudh-modi Medium - https://medium.com/@anirudh.modi2 Email - anirudh.modi2@gmail.com