Going offline with
Service Worker
Programable proxy
ServiceWorkerPageNetwork
Registration
navigator.serviceWorker.register('/worker.js')
.then( swRegistration => console.log('Success 🎆') )
.catch( err => console.log('Failure 💩', err) );
or (soon):
<head>
…
<link rel="serviceworker" href="worker.js" />
…
</head>
URL object
const url = new URL("https://example.com/api/search?query='dfua'");
if (url.hostname === 'example.com'
|| url.pathname.includes('/api/')
|| url.searchParams.has('query')) {
//...
}
Fetch API
fetch("https://example.com/data.json")
.then(response => {
if(response.ok) {
// ...
}
})
.catch(connectionFailed)
const request = new Request("https://example.com/endpoint", {
method: "POST",
headers: customHeaders,
body: '{"conf":"dfua"}'
});
fetch(request).then(processResponse);
Cache API
caches.open('cache-v1').then(cache => {
cache.put(request, response);
cache.add('/main.js');
cache.addAll(['/main.css', 'https://fonts.com/roboto.woff2']);
cache.match('/main.css').then(cachedResponse => {
if (cachedResponse) {
showResource(cachedResponse);
}
});
}).catch(err => console.error(err));
Cache, falling back to network
ServiceWorkerPageCacheNetwork12344
Putting it all togheter
self.addEventListener('fetch', event => {
const url = new URL(event.request.url);
if( url.pathname.startsWith('/article/') ) {
event.respondWith(
cache.match(event.request)
.then( cachedItem => {
if(cachedItem) return cachedItem;
return fetch(event.request)
.then( freshItem => {
cache.put(event.request, freshItem.clone());
return freshItem;
});
});
);
}
});
Network falling back to cache
ServiceWorkerPageNetworkCache1234
Revalidating caches
ServiceWorkerPageNetworkCache12345
Generic fallback
ServiceWorkerPageNetworkCache1 2 3 4 5
- fetch different image based on network capabilities
- cache content when user requests it
- render templates on-the-fly
- transpile code on-the-fly
- mock responses while developing
manifest.json
{
…
"gcm_sender_id": "593836075156"
}
Subscription
navigator.serviceWorker.register('/worker.js').then(swRegistration => {
swRegistration.pushManager.subscribe({
userVisibleOnly: true
}).then( sub => console.log('endpoint:', sub.endpoint) );
});
Handling requests
self.addEventListener('push', event => {
event.waitUntil(
self.registration.showNotification('Title', {
body: 'The Message',
icon: 'images/icon.png',
tag: 'my-tag'
}));
});
PushMessageServiceWorkerNetworkNotificationCache1234
SyncService WorkerNetwork12
Registration
navigator.serviceWorker.ready.then(swRegistration => {
swRegistration.sync.register('mySync');
});
Event
self.addEventListener('sync', event => {
if (event.tag == 'mySync') {
event.waitUntil(doSomeStuff());
}
});
Going offline with
Service Worker
Konrad Dzwinel