Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Offline Web Apps (Service Workers)
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Erik Hellman
August 03, 2017
Programming
180
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Offline Web Apps (Service Workers)
Erik Hellman
August 03, 2017
More Decks by Erik Hellman
See All by Erik Hellman
Wireless protocols for the next generation IoT devices
erikhellman
2
150
Working with Custom Android Devices and AOSP build system
erikhellman
2
690
Working with custom Android devices
erikhellman
2
520
Developing system apps without AOSP
erikhellman
2
810
State of BLE on Android in 2023
erikhellman
3
1.1k
State of BLE on Android in 2022
erikhellman
1
1.3k
The technical solutions behind Öppna Skolplattformen
erikhellman
0
280
Bluetooth Low Energy for Modern Android Development
erikhellman
1
1.1k
Introduction to Flutter
erikhellman
0
290
Other Decks in Programming
See All in Programming
楽しそうなつよつよエンジニアと目が死んでる僕/A brilliant engineer having a blast, and dead-eyed me.
3l4l5
2
230
属人化した知識を、 AIが辿れる地図にする
pkshadeck
PRO
1
200
AIと壁打ちしながら進めるコスト管理
fufuhu
1
1.4k
Hono + Inertia + React で LP を構築した話
oukayuka
2
120
2年かけて Deno に DOMMatrix を実装した話 / How I implemented DOMMatrix in Deno over two years
petamoriken
0
220
freeeにおけるEvalsの実践例の紹介
freee
PRO
0
140
AWS DevOps AgentのAzure接続機能を検証して見えた活用法/Use Cases Verified for the AWS DevOps Agent's Azure Connectivity Feature
masakiokuda
1
260
これって Effect でできたのでは? / TSKaigi Mashup Kansai #2
susisu
0
250
レビュー履歴をAIに食わせて、 Compose移行を加速するs
shihochan
0
170
「人を評価する AI」の設計と実装
ryoyanara
0
220
「寝てても仕事が進む」Claude Codeで組む第二の脳
tomoyafujita2016
0
350
初めての模倣学習とVLA
natsutan
0
130
Featured
See All Featured
Building Applications with DynamoDB
mza
96
7.2k
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
1
1.8k
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
1
300
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
3.7k
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
630
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
2
3.8k
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
240
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
From Legacy to Launchpad: Building Startup-Ready Communities
dugsong
0
300
The World Runs on Bad Software
bkeepers
PRO
72
12k
Reality Check: Gamification 10 Years Later
codingconduct
0
2.3k
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
350
Transcript
Offline Web Apps
None
None
Lie-fi
of users abandon sites that take longer than 3 seconds
to load 53%
60% of world-wide mobile connections are 2G
Service Workers
Service Workers are a client-side proxy Service worker (written in
Javascript) Cache Web server
Service Worker Lifecycle • Adds app-like lifecycle to a page
• Wakes up only when the OS says • Only responds to system events Activated Error Idle Active Terminated Install Register
• Adds app-like lifecycle to a page • Wakes up
only when the OS says • Only responds to system events Activated Error Idle Active Terminated Install Register Service Worker Lifecycle
Service Worker Lifecycle • Adds app-like lifecycle to a page
• Wakes up only when the OS says • Only responds to system events Activated Error Idle Active Terminated Install Register
Service Worker is for the SECOND load.
Implementing a Simple Service Worker
Register the Service Worker Activated Error Idle Active Terminated Install
Register
Register the Service Worker if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/service-worker.js')
.then(function(reg) { console.log('Service Worker Registered', reg); }) .catch(function(err) { console.log('Error registering Service Worker', err); }); }
Register the Service Worker if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/service-worker.js')
.then(function(reg) { console.log('Service Worker Registered', reg); }) .catch(function(err) { console.log('Error registering Service Worker', err); }); }
Add an install Event Handler Activated Error Idle Active Terminated
Install Register
Add an install Event Handler self.addEventListener('install', function(event) { return self.skipWaiting();
});
Pre-fetch the App Resources Activated Error Idle Active Terminated Install
Register
Pre-fetch the App Resources var cacheName = 'app-shell-cache-v1'; var filesToCache
= ['/', '/index.html', ...]; self.addEventListener('install', function(event) { event.waitUntil( caches.open(cacheName).then(function(cache) { return cache.addAll(filesToCache); }).then(function() { return self.skipWaiting(); }) ); });
Pre-fetch the App Resources var cacheName = 'app-shell-cache-v1'; var filesToCache
= ['/', '/index.html', ...]; self.addEventListener('install', function(event) { event.waitUntil( caches.open(cacheName).then(function(cache) { return cache.addAll(filesToCache); }).then(function() { return self.skipWaiting(); }) ); });
Pre-fetch the App Resources var cacheName = 'app-shell-cache-v1'; var filesToCache
= ['/', '/index.html', ...]; self.addEventListener('install', function(event) { event.waitUntil( caches.open(cacheName).then(function(cache) { return cache.addAll(filesToCache); }).then(function() { return self.skipWaiting(); }) ); });
Pre-fetch the App Resources var cacheName = 'app-shell-cache-v1'; var filesToCache
= ['/', '/index.html', ...]; self.addEventListener('install', function(event) { event.waitUntil( caches.open(cacheName).then(function(cache) { return cache.addAll(filesToCache); }).then(function() { return self.skipWaiting(); }) ); });
Add an activate Event Handler Activated Error Idle Active Terminated
Install Register
Add an activate Event Handler self.addEventListener('activate', function(e) { e.waitUntil( caches.keys().then(function(keyList)
{ return Promise.all(keyList.map(function(key) { if (key !== cacheName) { return caches.delete(key); } })); }) ); return self.clients.claim(); });
Add an activate Event Handler self.addEventListener('activate', function(e) { e.waitUntil( caches.keys().then(function(keyList)
{ return Promise.all(keyList.map(function(key) { if (key !== cacheName) { return caches.delete(key); } })); }) ); return self.clients.claim(); });
Not Done Yet… Activated Error Idle Active Terminated Install Register
None
Add a fetch Event Handler self.addEventListener('fetch', function(e) { e.respondWith( caches.match(e.request).then(function(response)
{ return response || fetch(e.request); }) ); });
Add a fetch Event Handler self.addEventListener('fetch', function(e) { e.respondWith( caches.match(e.request).then(function(response)
{ return response || fetch(e.request); }) ); });
Add a fetch Event Handler self.addEventListener('fetch', function(e) { e.respondWith( caches.match(e.request).then(function(response)
{ return response || fetch(e.request); }) ); });
Add a fetch Event Handler self.addEventListener('fetch', function(e) { e.respondWith( caches.match(e.request).then(function(response)
{ return response || fetch(e.request); }) ); });
Ready to Go! Activated Error Idle Active Terminated Install Register
Scope if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/service-worker.js') .then(function(reg) { console.log('Service
Worker Registered', reg); }) .catch(function(err) { console.log('Error registering Service Worker', err); }); }
Scope if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/service-worker.js') .then(function(reg) { console.log('Service
Worker Registered', reg); }) .catch(function(err) { console.log('Error registering Service Worker', err); }); }
Scope if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/scripts/s-worker.js') .then(function(reg) { console.log('Service
Worker Registered', reg); }) .catch(function(err) { console.log('Error registering Service Worker', err); }); }
Scope if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/service-worker.js') .then(function(reg) { console.log('Service
Worker Registered', reg); }) .catch(function(err) { console.log('Error registering Service Worker', err); }); }
Caching Strategies YOU are in control of the network
Cache, Falling Back to Network Page Service Worker Network Cache
X
Network, Falling Back to Cache Page Service Worker Network Cache
X
Cache, then Network Page Service Worker Network Cache
Generic Fallback Page Service Worker Network Cache X X
control You are in
Tools
Chrome Dev Tools
Chrome Dev Tools: the cache
Chrome Dev Tools: the cache
sw-toolbox
Cache first in sw-toolbox importScripts('/sw-toolbox.js'); toolbox.router.get('/(.*)', toolbox.cacheFirst, { origin: /\.googleapis\.com$/
});
sw-precache Node module
sw-precache precache.write('service-worker.js', { staticFileGlobs: ['**/*.{html,css}'], runtimeCaching: [ {urlPattern: '/', handler:
'fastest'}, {urlPattern: '/api/.*', handler: 'networkFirst', options: {networkTimeoutSeconds: 5} }, {urlPattern: '/posts/.*', handler: 'cacheFirst'}, {urlPattern: '/styles/.*', handler: 'cacheOnly'}, {urlPattern: '/inbox.json', handler: 'networkOnly'} ] });
PWA Codelab https://codelabs.developers.google.com/codelabs/your-first-pwapp
Service Workers the core underpinning Progressive Web Apps
Service Workers Web Apps will need to worry about lifecycle...
Thank You!