ANDRII DATSENKO <ASDatsenko@luxoft.com>
TECHNICAL LEAD
May 17, 2017
OFFLINE w/ ServiceWorkers
ERR_INTERNET_DISCONNECTED
![](http://www.luxoft.com/static/images/luxoft/luxoft-logo-retina.png)
![](http://www.luxoft.com/upload/iblock/36a/lxft_training_banner_ci.jpg)
SERVICE WORKERS
A service worker sits between your site and the network.
Page
SW
Network
OFFLINE EXPERIENCE
One component of Progressive Web Apps
PROGRESSIVE
WEB APP
-
Fast Performance
-
Instant Content Load
-
Push Notifications
-
Add to Home Screen
WEB WORKER
Service Workers are just one type of Worker. Web Workers in the browser allow us to run code in a separate worker thread.
NEW THREAD
JavaScript is a single threaded. However sometimes we need to do more than one thing at a time.
REGISTER SW
if('serviceWorker' in navigator) {
navigator.serviceWorker.register('./sw.js')
.then(reg => {
console.log('Service Worker Registered')
})
.catch(err => {
console.log(`Error registering worker ${err}`);
})
}
SW SCOPE
navigator.serviceWorker.register('./sw-api.js', { scope: '/api/' });
navigator.serviceWorker.register('./sw-assets.js', { scope: '/assets/' });
/assets/ Matches
- /assets/
- /assets/foo
- /foo/assets/
- /foo/assets/1
DEBUG
LIFECYCLE
Install
Active
INSTALL
self.addEventListener('install', function(e) {
caches.open('app-name')
.then((cache) => {
});
});
CACHE ALL
return cache.addAll([
'',
'js/script.js',
'css/style.css'
]);
Files have to be available!!
INTERCEPT REQUESTS
self.addEventListener('fetch', function(e) {
e.respondeWith(
caches.open('union-times')
.then((cache) => {
return caches
.match(e.request)
.then((res) => res);
});
})
);
});
INTERCEPT REQUESTS
return caches.match(e.request)
.then(function(res) {
return res || fetch(e.request).then(res => {
cache.put(e.request, res.clone());
return res;
});
});
FREQUENT UPDATES?
NETWORK FIRST
self.addEventListener('fetch', function(e) {
e.respondWith(
fetch(e.request)
.then((response) => networkThenCache(response,e))
.catch(() => pullFromCache(e))
);
});
NETWORK FIRST
function networkThenCache(response,e) {
return caches.open(cacheVersion)
.then(function(cache) {
return caches.match(e.request)
.then(function(res) {
cache.put(e.request, response.clone());
return response;
});
});
}
Optimistic
NETWORK FIRST
function pullFromCache(e) {
return caches.open(cacheVersion)
.then(function(cache) {
return caches.match(e.request)
.then(function(res) {
return res;
});
});
}
Pessimistic
CACHE CLEANUP?
CLEAR ON ACTIVATED
const cacheVersion = 'app-name-2.0.0';
self.addEventListener('activate', function(e) {
e.waitUntil(
caches.keys().then((cacheNames) => {
return Promise.all(
cacheNames
.filter((name) => name === cacheVersion)
.map((cache) => caches.delete(cache))
);
})
})
);
});
SW-TOOLBOX
toolbox.precache([
'/index.html',
'/site.css',
'/images/logo.png'
]);
toolbox.router.get(':foo/index.html', function(request, values) {
return new Response('Handled a request for ' + request.url +
', where foo is "' + values.foo + '"');
});
toolbox.router.post('/(.*)', apiHandler, {
origin: 'https://api.example.com'
});
LINKS
Q&A Time
ANDRII DATSENKO <ASDatsenko@luxoft.com>
TECHNICAL LEAD
May 17, 2017
OFFLINE w/ ServiceWorkers
ERR_INTERNET_DISCONNECTED
Offline experience with ServiceWorkers
By Andrew Dacenko
Offline experience with ServiceWorkers
- 1,541