18.10.2016 Views

* Progressive Web Apps

progressive-web-apps-roes-moosmann-gdg-hamburg-10-2016

progressive-web-apps-roes-moosmann-gdg-hamburg-10-2016

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

* <strong>Progressive</strong> <strong>Web</strong> <strong>Apps</strong>


Tim<br />

<strong>Web</strong> & Android Dev @ inovex<br />

Amsterdam, 2016<br />

Just a week ago<br />

Jonas<br />

<strong>Web</strong> & .NET Dev @ inovex


<strong>Progressive</strong> (Enhancement)<br />

Responsive<br />

Fresh (up-to-date)<br />

Secure (HTTPS)<br />

PWATF?<br />

Discoverable (Search-Engines)<br />

Installable<br />

Linkable (Shareable)<br />

App-like<br />

Connectivity independent<br />

https://goo.gl/GxtUkp


"The 3 pillars of the web are HTML, CSS & JavaScript. You<br />

can't expect to yank one out and have it still working."<br />

- Nolan Lawson, Fronteers 2016<br />

https://goo.gl/faHjtM


The Manifest


{<br />

}<br />

"name": "DevFest Hamburg",<br />

"short_name": "DevFest",<br />

"icons": [ … ],<br />

"display": "standalone",<br />

"start_url": "/?utm_source=manifest",<br />

"theme_color": "#FF00FF",<br />

"background_color": "#FFFFFF"<br />


All praise the<br />

Service Worker<br />

and Jake Archibald (@jaffathecake)


Push<br />

Sync<br />

Fetch


navigator.serviceWorker.register('/sw.js')<br />

sw.js<br />

self.addEventListener('install', (ev) => {<br />

const wait = caches.open('v1').then(cache => {<br />

return cache.addAll([<br />

'app.min.js',<br />

'app.min.css',<br />

// ...<br />

]);<br />

});<br />

ev.waitUntil(wait);<br />

});<br />

Installing<br />

Waiting<br />

Activating<br />

Activated


navigator.serviceWorker.register('/sw.js')<br />

sw.js<br />

Installing<br />

Waiting<br />

Activating<br />

Activated


navigator.serviceWorker.register('/sw.js')<br />

sw.js<br />

Installing<br />

self.addEventListener('activate', (ev) => {<br />

// old SW has been deleted;<br />

// this is about to take over;<br />

// clean up old caches;<br />

});<br />

Waiting<br />

Activating<br />

Activated


navigator.serviceWorker.register('/sw.js')<br />

sw.js<br />

Installing<br />

self.addEventListener('fetch', (ev) => {<br />

ev.respondWith(<br />

caches.match(ev.request).then(resp => {<br />

return resp || fetch(ev.request);<br />

})<br />

);<br />

});<br />

Waiting<br />

Activating<br />

Activated


GoogleChrome/sw-toolbox<br />

importScripts('libs/sw-toolbox.js');<br />

toolbox.precache(['app.min.js','app.min.css']);<br />

toolbox.router.get('/news/(.*)', toolbox.networkFirst);<br />

toolbox.cacheFirst<br />

toolbox.fastest<br />

toolbox.cacheOnly<br />

toolbox.networkOnly<br />

and more ...


GoogleChrome/sw-precache<br />

require('sw-precache').write('sw.js', {<br />

staticFileGlobs: ['build/**/*.{js,html,css,png,jpg,svg,woff}'],<br />

stripPrefix: 'build'<br />

});


Demo Time


<strong>Web</strong> Push Standards<br />

W3C Push API<br />

IETF webpush-protocol<br />

IETF webpush-encryption<br />

IETF webpush-vapid


Push<br />

Service<br />

{<br />

}<br />

"endpoint": "https:// ",<br />

"keys": {<br />

"p256dh": " ",<br />

"auth": " "<br />

}<br />

Application Server<br />

navigator.serviceWorker.ready.then(registration => {<br />

return registration.pushManager.subscribe({ userVisibleOnly: true });<br />

})<br />

.then(pushSubscription => {<br />

// send pushSubscription to application server<br />

});


Payload<br />

Push<br />

Service<br />

POST → endpoint<br />

Payload<br />

Application Server<br />

self.addEventListener('push', ev => {<br />

});<br />

new Notification(...);


Push<br />

Service<br />

POST Header<br />

- Authorization: <strong>Web</strong>Push [@]<br />

Private<br />

Public<br />

Application Server<br />

navigator.sericeWorker.ready.then(registration => {<br />

});<br />

registration.pushManager.subscribe({ applicationServerKey: });


And since we all<br />

crypto:<br />

web-push-libs/web-push


Demo Time


Background Sync<br />

navigator.serviceWorker.ready.then(sw => {<br />

sw.sync.register('send-msgs');<br />

});<br />

IndexedDB<br />

self.addEventListener('sync', ev => {<br />

if (ev.tag === 'send-msgs') {<br />

const promise = sendSomeCachedData();<br />

ev.waitUntil(promise);<br />

}<br />

});


Demo Time<br />

Photo by Frances Berriman (CC-BY-NC-ND 2.0)


Browser Support<br />

<strong>Web</strong> App Manifest<br />

*<br />

Service Workers<br />

Push API<br />

Background Sync<br />

27


The Future<br />

Better Browser Support<br />

More Sync Options<br />

More and more APIs

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!