* Progressive Web Apps
progressive-web-apps-roes-moosmann-gdg-hamburg-10-2016
progressive-web-apps-roes-moosmann-gdg-hamburg-10-2016
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