André Kelling
FE dev
by
FE dev @
Introduction
last change Mar. 2018
André Kelling
©
Speed is everything!
It's about a JavaScript file that can control a websites behaviour.
A new layer at the front end.
It's a WebWorker.
The Service Worker is a generic entry point for event-driven background processing in the Web Platform that is extensible by other specifications.
Improved experience for returning visitors.
"you have granular control over everything."
"functionality that would normally require a native application—are coming to the web."
"I'm biased, but I think ServiceWorker changes the scope of the web more than any feature since XHR."
most useful for mobile devices!
Using a service worker is great to build PWA's
not direct part of the Service Worker:
Progressive & Responsive, Native Features, Linkable, Installable
Sir Wiz
common example
A Service Worker needs to get initially registered inside your favorite JS file.
Wether on a whole origin or inside a subset / the scope.
if ('serviceWorker' in navigator) {
navigator.serviceWorker
.register('./service-worker.js')
.then(function() { console.log('Service Worker Registered'); });
}
if ('serviceWorker' in navigator) {
navigator.serviceWorker
.register('./blog/service-worker.js')
.then(function() { console.log('SW Registered for Blog pages'); });
}
progressive enhancement!
1. Download
once registered the service worker gets downloaded
var cacheName = 'myFilesToCache-v1';
var filesToCache = [
'./',
'./index.html',
'./scripts/app.js',
'./inline.css',
'./images/wind.png'
];
self.addEventListener('install', function(e) {
console.log('[ServiceWorker] Install');
e.waitUntil(
caches.open(cacheName).then(function(cache) {
console.log('[ServiceWorker] Caching app shell');
return cache.addAll(filesToCache);
})
);
});
2. Install
once installed the SW adds files to cache
3. Activate
used to remove old caches
old caches will get identified by the name of the new cache
var cacheName = 'myFilesToCache-v2';
// var filesToCache here
// install event here
self.addEventListener('activate', function(e) {
console.log('[ServiceWorker] Activate');
e.waitUntil(
caches.keys().then(function(keyList) {
return Promise.all(keyList.map(function(key) {
if (key !== cacheName) {
console.log('[ServiceWorker] Removing old cache', key);
return caches.delete(key);
}
}));
})
);
return self.clients.claim();
});
e.g. `fetch` event listener can store by JS fetched resources.
& Restrictions
Needs to be added as progressive enhancement!
Check jakearchibald.github.io/isserviceworkerready/ for details.
Service Worker makes usage of JS promises.
So ES6 is mandatory!
But as seen before, all browsers supporting service worker
are already supporting ES6 too.
Because of security reasons service worker
will just run on sites delivered over HTTPS.
Development on http://localhost will work.
It's considered to be a "secure origin".
Storage is limited by browser's
Cache or Quota API.
A single service worker can control many pages. Each time a page within your scope is loaded, the service worker is installed against that page and operates on it.
example:
could have a second SW running for
pre-fetching first 5 blog entry sites
A Service Worker stays active until all Tabs or Windows with your Web App are closed.
Once the user freshly re-opens your Web App a new Service Worker can get active.
😱
This is to prevent user's data corruption or other bad impacts the user could experience while browsing on your site.
☝️
A new cache is opened on SW's install event when there is an incremented version number or different cache naming.
var cacheName = 'weatherPWAs-v6';
The new SW has to wait.
Cache is shared between all open Tabs.
https://github.com/GoogleChromeLabs/sw-toolbox
https://github.com/GoogleChromeLabs/sw-precache
"The team behind sw-toolbox and sw-precache have been busy creating Workbox, which is a collection of libraries and tools that make it easy to build offline web apps. It’s a joining of sw-toolbox and sw-precache with more features and a modern codebase."
npm install workbox-cli --global
Already working fine with:
module.exports = {
"globDirectory": "./",
"globPatterns": [
"site/templates/css/style.min.css",
"site/templates/js/build/production.min.js",
"site/templates/fonts/**/*.{eot,svg,ttf,woff}"
],
"swDest": "sw.js",
"clientsClaim": true,
"skipWaiting": true
};
and generate with
workbox generate:sw
Your workbox-cli-config.js file:
gulp.task('generate-service-worker', () => {
return workbox.generateSW({
globDirectory: buildDir,
globPatterns: ['**\/*.{png,css,js,svg,jpg,json}'],
swDest: buildDir+`/sw.js`,
clientsClaim: true,
skipWaiting: true
}).then(() => {
console.info('Service worker generation completed.');
}).catch((error) => {
console.warn('Service worker generation failed: ' + error);
});
});
skipWaiting enables a service worker to get active even if the user doesn't freshly re-opens your Web App. (doesn't works that well)
👏
By André Kelling
functionality that would normally require a native application