Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Offlinefähige Browseranwendungen: Progressive Web-Apps mit Angular

Offlinefähige Browseranwendungen: Progressive Web-Apps mit Angular

Manfred Steyer

February 26, 2017
Tweet

More Decks by Manfred Steyer

Other Decks in Programming

Transcript

  1. Über mich … • Manfred Steyer • SOFTWAREarchitekt.at • Trainer

    & Consultant • Google Developer Expert (GDE) • MVP • Focus: Angular Page  2 ManfredSteyer
  2. vs.

  3. PWAs implementieren Moderne Browser Technologien •Service Worker •Web App Manifest

    •IndexedDb & Co. Muster •Caching Patterns •App Shell Pattern •Universal JS
  4. Was sind Service Worker? • Hintergrund-Tasks • Werden von Web

    App installiert • Können ohne Web App laufen • Können sich deaktivieren und bei Ereignissen wieder aktivieren • Nur HTTPS (außer localhost) • Kein XHR, aber fetch
  5. Service Worker und Offline • Anfragen abfangen • Entscheiden, wie

    auf Anfragen zu antworten ist • Same Origin Policy • Caching Muster • Cache only • Network only • Try cache first, then network • Try network first, then cache • etc.
  6. Service Worker registrieren if('serviceWorker' in navigator) { navigator .serviceWorker .register('/sw.js',

    { scope: '/' }) .then((r) => { console.debug('service worker started!'); }); }
  7. Service Worker Toolbox //sw-with-toolbox.js importScripts('/node_modules/sw-toolbox/sw-toolbox.js'); toolbox.precache(CACHE_FILES); toolbox.router.get('/(.*)', toolbox.networkOnly, {origin: 'http://www.angular.at'});

    toolbox.router.default = toolbox.cacheFirst; <script src="node_modules/sw-toolbox/companion.js" data-service-worker="sw-with-toolbox.js"></script> Array kann generiert werden!
  8. Fallback für Safari & Co. • AppCache • Weniger Feature

    • Keine große Auswahl an Caching Patterns • Cache only • Network only
  9. Daten offline speichern • LocalStorage • WebDb (deprecated aber hier)

    • IndexedDb • Gute Idee: Abstraktion nutzen, z. B. PouchDB • Herausforderung: Quotas!
  10. PouchDb const db = new PouchDB("bookingDb"); db.get('bookings').then(entity => { //

    do something with entity }); var entity = { _id: "bookings", bookings: bookings } db.put(entity).then(_ => { console.debug('stored!'); });
  11. App Shell • Shell im Cache (Service Worker) • Daten

    aus Cache (e. g. PouchDb) • Kann sofort angezeigt werden • Daten aus Cache werden nach dem Laden durch aktuelle Daten ersetzt App Shell Content
  12. "Installation" am Home Screen { "name": "Flight PWA-Demo", "short_name": "Flight-PWA",

    "icons": [{ "src": "images/touch/icon-128x128.png", "sizes": "128x128", "type": "image/png" }, […] ], "start_url": "/index.html?homescreen=1", "display": "standalone", […] }
  13. Manifest referenzieren <!-- Web Application Manifest --> <link rel="manifest" href="manifest.json">

    <!-- Add to homescreen for Safari on iOS --> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <meta name="apple-mobile-web-app-title" content="Web Starter Kit"> <link rel="apple-touch-icon" href="images/touch/apple-touch-icon.png">
  14. Background Sync • App fordert Background Sync an • Service

    Worker führt Sync Event aus, wenn es passend erscheint (Netzwerk, Akku, …) • Pläne für periodische Background Sync
  15. Background Sync anfordern let nav: any = navigator; if ('serviceWorker'

    in nav && 'SyncManager' in window) { nav.serviceWorker.ready .then(reg => { return reg.sync.register('upload'); }) .catch(_ => { return this.buchungService.upload(); }); } else { this.buchungService.upload(); } Tag
  16. Sync Event in Service Worker context.addEventListener('sync', function(event) { console.debug("Service Worker:

    sync, tag=" + event.tag); if (event.tag == 'upload') { event.waitUntil(bs.upload().then(_ => console.debug('background-upload finished'))); } });
  17. Push Notifications Browser Push-Service Web API 4. Benachrichtigung 2. Url

    + ID 3. Benachrichtigung für Browser 1. Anmelden
  18. Für Push registrieren let nav:any = navigator; if ('serviceWorker' in

    navigator) { nav.serviceWorker.ready.then(function(reg) { reg.pushManager.subscribe({ userVisibleOnly: true }).then(function(sub) { console.log('endpoint:', sub.endpoint); // Send endpoint with id over to web api }); }).catch(function(error) { […] }); }
  19. Auf Push in Service Worker reagieren context.addEventListener('push', function(event: any) {

    event.waitUntil(bs.sync().then(p => context.registration.showNotification("Delay", { body: 'Your flight is delayed', icon: '/images/touch/icon-128x128.png', tag: 'my-tag' }))); });
  20. Mobile Toolkit • Scaffolding für Angular 2 PWA mit Angular

    CLI • Hilft beim Start • Generiert Web App Manifest • Generiert App Shell • Angular Universal • Service Worker für Caching • AppCache as Fallback for Safari & Co.
  21. Summary Das Beste von Web und Native Progressive Enhancements Offline

    Browser DBs Background Sync Push Angular Mobile Toolkit M&M's können den Tag retten!