2016



2016

1 0


swpresentation


On Github kdzwinel / swpresentation

Going offline with

Service Worker

Konrad Dzwinel

Hello!

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

Push

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

Background sync

SyncService WorkerNetwork12

Registration

navigator.serviceWorker.ready.then(swRegistration => {
  swRegistration.sync.register('mySync');
});

Event

self.addEventListener('sync', event => {
  if (event.tag == 'mySync') {
    event.waitUntil(doSomeStuff());
  }
});

DevTools

Is ServiceWorker ready?

Thank you!

@kdzwinel
Going offline with Service Worker Konrad Dzwinel