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
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
660
Working with custom Android devices
erikhellman
2
510
Developing system apps without AOSP
erikhellman
2
790
State of BLE on Android in 2023
erikhellman
3
1k
State of BLE on Android in 2022
erikhellman
1
1.3k
The technical solutions behind Öppna Skolplattformen
erikhellman
0
270
Bluetooth Low Energy for Modern Android Development
erikhellman
1
1.1k
Introduction to Flutter
erikhellman
0
280
Other Decks in Programming
See All in Programming
鹿野さんに聞く!『TypeScriptコードレシピ集』で磨く実践力
tonkotsuboy_com
4
1.1k
これからAgentCoreを触る方へトレンドはGatewayです
har1101
6
480
Go1.27で導入されるジェネリクスメソッドでできること
mackee
0
280
JAWS-UG横浜 #102 AWSサ終供養LT会 成仏できない AWS サービスたち 〜本日、三体供養します〜
maroon1st
0
110
共通化で考えるべきは、実装より公開する型だった
codeegg
0
210
えっ!!コードを読まずに開発を!?
hananouchi
0
190
ECSアプリログをFireLensでコスト削減しようとしたけど諦めた話 in Fargate×Node.js
akihisaikeda
2
4.3k
Claude Opus 4.6以後の受託開発エンジニアの変化(Claude Code開発ノウハウ大公開スペシャルbyクラスメソッド)
iidatakuma
1
600
광주소프트웨어마이스터고등학교 DevFest 특강 - 바이브 코딩 시대에서 주니어 개발자로 살아남는 방법
utilforever
1
100
Even G2とAWSで推しのエージェントを召喚しよう!
har1101
1
160
Developing with AI Agents — Codex, Claude Code & Cowork Practical Guide
x5gtrn
PRO
0
1.4k
【やさしく解説 設計編 #0】DDDのコード、読めるのに分からない人へ
panda728
PRO
2
260
Featured
See All Featured
How to Ace a Technical Interview
jacobian
281
24k
The Invisible Side of Design
smashingmag
301
52k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
610
Testing 201, or: Great Expectations
jmmastey
46
8.2k
Java REST API Framework Comparison - PWX 2021
mraible
34
9.5k
Principles of Awesome APIs and How to Build Them.
keavy
128
18k
The Illustrated Children's Guide to Kubernetes
chrisshort
51
53k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
23k
Context Engineering - Making Every Token Count
addyosmani
9
1k
Ruling the World: When Life Gets Gamed
codingconduct
0
280
My Coaching Mixtape
mlcsv
0
170
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!