Slide 1

Slide 1 text

PWA Deep Dive Offlineanwendungen im Griff Christian Liebel @christianliebel Consultant

Slide 2

Slide 2 text

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 & Cloud & Enterprise Blockchain

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

PWA Deep Dive Offlineanwendungen im Griff Responsive Linkable Discoverable Installable App-like Connectivity Independent Fresh Safe Re-engageable Progressive

Slide 5

Slide 5 text

PWA Deep Dive Offlineanwendungen im Griff

Slide 6

Slide 6 text

Service Worker & Cache API Source Files & Assets App & IndexedDB Structured Data PWA Deep Dive Offlineanwendungen im Griff Connectivity Independent

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

PWA Deep Dive Offlineanwendungen im Griff Offline First System Website HTML/JS Local storage Central adapter Remote storage Server Internet

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

Key Technology Service Worker Service Worker Internet Website HTML/JS Cache fetch Offlineanwendungen im Griff PWA Deep Dive

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

Lifecycle PWA Deep Dive Offlineanwendungen im Griff Service Worker Installing Parsed Error Activated Idle Terminated fetch/ message

Slide 17

Slide 17 text

Platform Support Service Worker Offlineanwendungen im Griff PWA Deep Dive 17 11.1 44 40 4.1 Chrome 40 11.3

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

Debugging PWA Deep Dive Offlineanwendungen im Griff Service Worker

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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)

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

Debugging PWA Deep Dive Offlineanwendungen im Griff Cache API

Slide 27

Slide 27 text

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/

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

Commands workbox wizard workbox generateSW workbox injectManifest PWA Deep Dive Offlineanwendungen im Griff Workbox LIVE DEMO

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

Client Library import { Workbox } from 'workbox-window'; if ('serviceWorker' in navigator) { const wb = new Workbox('service-worker.js'); wb.addEventListener('installed', event => { if (event.isUpdate) { if (confirm('New content is available! Click OK to refresh')) { window.location.reload(); } } }); wb.register(); } PWA Deep Dive Offlineanwendungen im Griff Workbox https://medium.com/@webmaxru/workbox-4-implementing-refresh-to-update-version-flow-using-the-workbox-window-module-41284967e79c

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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 Demo App LIVE DEMO

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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) • WebSQL (deprecated) • IndexedDB PWA Deep Dive Offlineanwendungen im Griff IndexedDB

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

Browser Support PWA Deep Dive Offlineanwendungen im Griff IndexedDB 10 7.1 4 11

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

const dexie = new Dexie('Meine-DB'); dexie.version(1).stores({ todos: 'id++,done' }); PWA Deep Dive Offlineanwendungen im Griff Dexie.js LIVE DEMO

Slide 45

Slide 45 text

IndexedDB Debugging PWA Deep Dive Offlineanwendungen im Griff Dexie.js

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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 LIVE DEMO

Slide 49

Slide 49 text

Browser Support PWA Deep Dive Offlineanwendungen im Griff Background Sync API WIP — WIP 49

Slide 50

Slide 50 text

https://pwapraxis.liebel.io PWA Deep Dive Offlineanwendungen im Griff Demo LIVE DEMO

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

Thank you for your kind attention! Christian Liebel @christianliebel [email protected]