PWA Deep Dive: Offlineanwendungen im Griff

PWA Deep Dive: Offlineanwendungen im Griff

Zentrale Eigenschaft jeder Progressive Web App (PWA) ist die Verbindungsunabhängigkeit. Dank dem Service Worker funktioniert die App auch dann, wenn der Anwender gerade offline ist: im Tunnel, im Park oder im Dschungel. Bei der Generierung eines Service Workers hilft das Toolkit Workbox. Anwenderdaten werden hingegen in der Browserdatenbank IndexedDB hinterlegt. Wo Daten offline gehalten werden, müssen aber auch deren Synchronisierung und Konfliktauflösung in der Architektur bedacht werden. Christian Liebel von Thinktecture zeigt Ihnen am Beispiel einer in Angular geschriebenen Anwendung die Mechanik hinter dem Service-Worker-Cache und der Browserdatenbank IndexedDB, sodass es auch Ihre PWA mit den nativen Gegenstücken problemlos aufnehmen kann.

Dieser Talk richtet sich an Entwickler, die grob wissen, um was es bei Progressive Web Apps geht. In diesem Track gibt es auch den passenden Grundlagenvortrag („Progressive Enhancement im Web: PWA-Grundlagen“), der Ihnen dieses Verständnis vermittelt. Bitte nehmen Sie ein Smartphone mit, um ggf. die Demoanwendung auf dem eigenen Gerät ausprobieren zu können.

12c88a3a10478fa18d0363b3ba3d9df1?s=128

Christian Liebel

September 24, 2019
Tweet

Transcript

  1. PWA Deep Dive Offlineanwendungen im Griff Christian Liebel @christianliebel Consultant

  2. Hello, it’s me. PWA Deep Dive Offlineanwendungen im Griff Christian

    Liebel Follow me: @christianliebel Blog: christianliebel.com Email: christian.liebel @thinktecture.com Cross-Platform & Serverless
  3. PWA Deep Dive Offlineanwendungen im Griff - Das PWA-Anwendungsmodell -

    Web App Manifest - Service Worker und Cache API - Workbox: Toolkit für PWAs - Angular-Unterstützung für PWAs - Natives Look & Feel - Migrieren & veröffentlichen - Payment Request API & Apple Pay www.rheinwerk-verlag.de/4707
  4. PWA Deep Dive Offlineanwendungen im Griff Responsive Linkable Discoverable Installable

    App-like Connectivity Independent Fresh Safe Re-engageable Progressive
  5. PWA Deep Dive Offlineanwendungen im Griff

  6. Service Worker & Cache API Source Files & Assets App

    & IndexedDB Structured Data PWA Deep Dive Offlineanwendungen im Griff Connectivity Independent
  7. Offline First Service Worker Cache API Workbox Angular Demo App

    IndexedDB Dexie.js Background Sync API PWA Deep Dive Offlineanwendungen im Griff Talking Points
  8. Offline First Service Worker Cache API Workbox Angular Demo App

    IndexedDB Dexie.js Background Sync API PWA Deep Dive Offlineanwendungen im Griff Talking Points
  9. Offline Capability Challenge: Connection strength varies a lot (especially en

    route) Lie-Fi: Connection strength of a public WiFi is weak or even completely offline Goal: App works offline or with a weak connection at least within the possibilities (e.g. OneNote) PWA Deep Dive Offlineanwendungen im Griff Offline First
  10. Principle PWA Deep Dive Offlineanwendungen im Griff Offline First -

    Draft and implement offline support first - Think about synchronization & conflicts - Don’t treat offline as an error - Make offline the default - Everything must be offline capable
  11. PWA Deep Dive Offlineanwendungen im Griff Offline First System Website

    HTML/JS Local storage Central adapter Remote storage Server Internet
  12. Locking Pessimistic - System locks access to resource if it

    is used by another user - No conflicts - Users don’t like this (offline = no locking possible!) Optimistic - Users can access arbitrary resources anytime - Requires data synchronization & conflict resolution (strategies depend on domain) PWA Deep Dive Offlineanwendungen im Griff Offline First
  13. Offline First Service Worker Cache API Workbox Angular Demo App

    IndexedDB Dexie.js Background Sync API PWA Deep Dive Offlineanwendungen im Griff Talking Points
  14. Key Technology Service Worker Service Worker Internet Website HTML/JS Cache

    fetch Offlineanwendungen im Griff PWA Deep Dive
  15. Worker snippet is executed in an own thread Worker can’t

    manipulate the parent document’s DOM Communication via thin API (postMessage) Acts as a controller/proxy/interceptor Performs background tasks Has to be installed before usage Relation: Scope (origin + path) Lifetime: Unrelated to tab/window PWA Deep Dive Offlineanwendungen im Griff Service Worker
  16. Lifecycle PWA Deep Dive Offlineanwendungen im Griff Service Worker Installing

    Parsed Error Activated Idle Terminated fetch/ message
  17. Platform Support Service Worker Offlineanwendungen im Griff PWA Deep Dive

    17 11.1 44 40 4.1 Chrome 40 11.3
  18. Basic Implementation navigator.serviceWorker.register('sw.js') .then(subscription => console.log(subscription)) .catch(err => console.error('Fehler', err));

    self.addEventListener('install', event => {}); self.addEventListener('activate', () => {}); self.addEventListener('fetch', event => {}); PWA Deep Dive Offlineanwendungen im Griff Service Worker LIVE DEMO
  19. Debugging PWA Deep Dive Offlineanwendungen im Griff Service Worker

  20. Offline First Service Worker Cache API Workbox Angular Demo App

    IndexedDB Dexie.js Background Sync API PWA Deep Dive Offlineanwendungen im Griff Talking Points
  21. Introduction Cache: Key-value storage Key: HTTP(S) request, value: HTTP(S) response

    Survives browser restarts (Safari: unused caches are cleared “after a few weeks”) Can be accessed from both service worker and website Isolated per origin (protocol + hostname + port) Multiple named caches per origin Cache operations are asynchronous (Promises) PWA Deep Dive Offlineanwendungen im Griff Cache API
  22. Usage 1. Open a cache 2. Store/read responses from the

    cache PWA Deep Dive Offlineanwendungen im Griff Cache API await caches.open('images') await cache.put(req, res) await cache.add(req) await cache.match(req)
  23. and Service Worker PWA Deep Dive Offlineanwendungen im Griff Cache

    API Installing Parsed Error Activated Idle Terminated fetch/ message Install cache content Remove old caches Deliver from cache
  24. Adding Requests to The Cache self.addEventListener('install', event => { event.waitUntil(

    caches.open('pwa-demo-v1') .then(cache => cache.addAll(['/', '/index.html'])) .then(() => self.skipWaiting()) ); }); PWA Deep Dive Offlineanwendungen im Griff Cache API LIVE DEMO
  25. Delivering from The Cache self.addEventListener('fetch', event => { event.respondWith( caches.match(event.request)

    .then(response => response || fetch(event.request)) ); }); PWA Deep Dive Offlineanwendungen im Griff Cache API LIVE DEMO
  26. Debugging PWA Deep Dive Offlineanwendungen im Griff Cache API

  27. Caching Strategies 1. Cache only 2. Network only 3. Cache

    falling back to network 4. Cache & network race 5. Network falling back to cache 6. Cache then network 7. Generic Fallback 8. Service-Worker-side templating PWA Deep Dive Offlineanwendungen im Griff Cache API https://jakearchibald.com/2014/offline-cookbook/
  28. PWA Deep Dive Offlineanwendungen im Griff Cache Then Network System

    Website HTML/JS Cache Storage Remote storage Server Internet 2. fetch HTTP Service Worker 1. lookup
  29. Use Cases Service Worker - everything that’s part of a

    website/app version - application source files - assets Application - dynamic content known during runtime - “read later”, profile images, … - lookup without fetch PWA Deep Dive Offlineanwendungen im Griff Cache API
  30. Offline First Service Worker Cache API Workbox Angular Demo App

    IndexedDB Dexie.js Background Sync API PWA Deep Dive Offlineanwendungen im Griff Talking Points
  31. Overview Toolchain by Google: Service Worker generator and runtime library

    Automatically creates a Service Worker implementation for you Can extend an existing Service Worker implementation with caching Command line tool: workbox npm i -g workbox-cli PWA Deep Dive Offlineanwendungen im Griff Workbox
  32. Commands workbox wizard workbox generateSW workbox injectManifest PWA Deep Dive

    Offlineanwendungen im Griff Workbox LIVE DEMO
  33. Routing & Strategies workbox.routing.registerRoute( new RegExp('/social-timeline/'), workbox.strategies.networkFirst() ); PWA Deep

    Dive Offlineanwendungen im Griff Workbox
  34. Offline First Service Worker Cache API Workbox Angular Demo App

    IndexedDB Dexie.js Background Sync API PWA Deep Dive Offlineanwendungen im Griff Talking Points
  35. PWA Setup Angular supports service worker and cache manifest generation

    (for productive builds only) npm i -g @angular/cli ng new myApp cd myApp ng add @angular/pwa ng build --prod PWA Deep Dive Offlineanwendungen im Griff Angular LIVE DEMO
  36. Update Process PWA Deep Dive Offlineanwendungen im Griff Angular V1

    V2 V2 V1 V1 V2 Server Browser
  37. SwUpdate The SwUpdate service provides an available observable that fires

    when there’s an update. As a result, the user can be prompted to reload the website. PWA Deep Dive Offlineanwendungen im Griff Angular
  38. Offline First Service Worker Cache API Workbox Angular Demo App

    IndexedDB Dexie.js Background Sync API PWA Deep Dive Offlineanwendungen im Griff Talking Points
  39. Motivation The web platform has different techniques to store arbitrary

    data (e.g. application state) offline: • Web Storage API (Local Storage/Session Storage—synchronous!) • Cookies (inconvenient) • IndexedDB PWA Deep Dive Offlineanwendungen im Griff IndexedDB
  40. Overview Indexed Database (IndexedDB) is a database in the browser

    capable of storing structured data in tables with keys and value Data is stored permanently (survives browser restarts) Service Worker and website share access to the same IndexedDB database (e.g. for synchronization purposes) PWA Deep Dive Offlineanwendungen im Griff IndexedDB
  41. Browser Support PWA Deep Dive Offlineanwendungen im Griff IndexedDB 10

    7.1 4 11
  42. Offline First Service Worker Cache API Workbox Angular Demo App

    IndexedDB Dexie.js Background Sync API PWA Deep Dive Offlineanwendungen im Griff Talking Points
  43. Overview Dexie is a minimalistic wrapper for IndexedDB Operations are

    based on promises instead of callbacks Near native performance (also for bulk inserts) Open-source PWA Deep Dive Offlineanwendungen im Griff Dexie.js
  44. Table API const table = db.table('todos'); table.toArray() // get all

    items as an array table.add() // insert an object table.put() // update or insert an object table.filter(i => i.id !== 3) // apply JS filter on value table.where({ name: 'Peter' }) // query items by key PWA Deep Dive Offlineanwendungen im Griff Dexie.js
  45. …and TypeScript class MyAppDatabase extends Dexie { todos: Dexie.Table<Todo, number>;

    constructor () { super('MyTodoDatabase'); this.version(1).stores({ todos: '++id', }); this.todos = this.table('todos'); } } PWA Deep Dive Offlineanwendungen im Griff Dexie.js LIVE DEMO
  46. IndexedDB Debugging PWA Deep Dive Offlineanwendungen im Griff Dexie.js

  47. https://pwapraxis.liebel.io PWA Deep Dive Offlineanwendungen im Griff Dexie.js LIVE DEMO

  48. Offline First Service Worker Cache API Workbox Angular Demo App

    IndexedDB Dexie.js Background Sync API PWA Deep Dive Offlineanwendungen im Griff Talking Points
  49. Syncs data when the client is next online (if the

    client is already online, syncs immediately) This also works when the client application closed Currently only supports one-off synchronization PWA Deep Dive Offlineanwendungen im Griff Background Sync API
  50. self.addEventListener('sync', event => { if (event.tag === 'upload-photos') { event.waitUntil(/*

    … */); } }); registration.sync.register('upload-photos'); PWA Deep Dive Offlineanwendungen im Griff Background Sync API
  51. Browser Support PWA Deep Dive Offlineanwendungen im Griff Background Sync

    API WIP — WIP 49
  52. Make use of the Offline First pattern Use Cache API

    for HTTPS requests Use IndexedDB for structured data Use Service Workers for initial caching and delivering cached content Think about data synchronization & conflict handling for structured data Background Sync API can sync data even when the app is closed Make your users happy! PWA Deep Dive Offlineanwendungen im Griff Summary
  53. Thank you for your kind attention! Christian Liebel @christianliebel christian.liebel@thinktecture.com