Service Worker
by
FE dev @
Introduction
last change Mar. 2018
André Kelling
©
Speed is everything!
Service Worker
- What is that?
- Use Cases
- Lifecycle
- Requirements
- Debugging
- Tools
Table of contents
What is that?
What is that?
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.
Description
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."
What is that?
Quotes
- Development started before May 2014
- Replacement for AppCache
- a user centred technology
- API provided by Browser (Navigator object)
- "made for" Offline First strategy
What is that?
Technical Background
Use Cases
Use Cases
Performance
- performance enhancements by pre-fetching resources
prefetch data for next article pages your user probably visits - reducing network request for chosen assets
cache first approach - service worker is fully async / a not blocking resource
it's not part of your DOM manipulating JS - load balancing possibility
load from desired server
Use Cases
Offline
- acts as a proxy server between App and Browser
no network connection needed - provide a customised offline fallback experience.
such as offline pages similar to 404 pages - granular cache control to control how App behaves
control how google analytics can work while offline
most useful for mobile devices!
Use Cases
Progressive Web App's
Using a service worker is great to build PWA's
- Connectivity independent
- App-like - functionality is separated from content
- Fast and Fresh - keeps data in sync
- Engaging - via Push Notifications
not direct part of the Service Worker:
Progressive & Responsive, Native Features, Linkable, Installable
Use Cases
more
Sir Wiz
Lifecycle
common example
Lifecycle
Registration
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!
Lifecycle
Install
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
Lifecycle
Activate
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();
});
Lifecycle
e.g. `fetch` event listener can store by JS fetched resources.
Requirements
& Restrictions
Requirements
Browser
Needs to be added as progressive enhancement!
Check jakearchibald.github.io/isserviceworkerready/ for details.
Requirements
JavaScript
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.
Requirements
HTTPS
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".
Restriciton
Cache Limitation
Storage is limited by browser's
Cache or Quota API.
Restriction
Scope
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
Restriction
User centred
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.
☝️
Restriction
Waiting
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.
Debugging
Debugging
Info
Cache is shared between all open Tabs.
Debugging
in Chrome
Debugging
in Chrome
- clear cache storage
- try offline
- update on reload!
- [cmd + shift + r] works fine too
Debugging
in Firefox
Tools
Tools
Obsolete
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."
Tools
Workbox
npm install workbox-cli --global
Already working fine with:
Tools
Workbox Node example
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:
Tools
Workbox Gulp example
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)
👏