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
Progressive Web Apps with React
Search
Jonathan Mills
October 10, 2018
Technology
0
52
Progressive Web Apps with React
Jonathan Mills
October 10, 2018
Tweet
Share
More Decks by Jonathan Mills
See All by Jonathan Mills
Javascript’s scary side
jonathanfmills
0
480
Keeping Up
jonathanfmills
1
220
Other Decks in Technology
See All in Technology
予期せぬコストの急増を障害のように扱う――「コスト版ポストモーテム」の導入とその後の改善
muziyoshiz
1
1.6k
Cosmos World Foundation Model Platform for Physical AI
takmin
0
420
仕様書駆動AI開発の実践: Issue→Skill→PRテンプレで 再現性を作る
knishioka
2
610
2026年、サーバーレスの現在地 -「制約と戦う技術」から「当たり前の実行基盤」へ- /serverless2026
slsops
2
220
名刺メーカーDevグループ 紹介資料
sansan33
PRO
0
1k
Amazon S3 Vectorsを使って資格勉強用AIエージェントを構築してみた
usanchuu
3
440
20260204_Midosuji_Tech
takuyay0ne
1
130
プロポーザルに込める段取り八分
shoheimitani
1
180
入社1ヶ月でデータパイプライン講座を作った話
waiwai2111
1
250
AWS Network Firewall Proxyを触ってみた
nagisa53
0
150
SREのプラクティスを用いた3領域同時 マネジメントへの挑戦 〜SRE・情シス・セキュリティを統合した チーム運営術〜
coconala_engineer
2
610
Meshy Proプラン課金した
henjin0
0
250
Featured
See All Featured
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.3k
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
0
100
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
1.8k
Balancing Empowerment & Direction
lara
5
880
Automating Front-end Workflow
addyosmani
1371
200k
Game over? The fight for quality and originality in the time of robots
wayneb77
1
110
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
55
The SEO identity crisis: Don't let AI make you average
varn
0
64
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
63
The untapped power of vector embeddings
frankvandijk
1
1.6k
Breaking role norms: Why Content Design is so much more than writing copy - Taylor Woolridge
uxyall
0
160
Transcript
@ j o n a t h a n f
m i l l s #reactPWA P R O G R E S S I V E W E B A P P S W I T H R E A C T
None
None
None
Progressive Web Apps to the rescue!
What is a PWA? RELIABLE
What is a PWA? RELIABLE FAST
What is a PWA? RELIABLE FAST ENGAGING
Demo
None
Service Workers
Have you heard of a Web Worker?
ServiceWorker != WebWorker
None
if('serviceWorker' in navigator) { navigator.serviceWorker.register('/offline.js', { scope: '/' }) .then(function(registration)
{ console.log('Service Worker Registered'); }); navigator.serviceWorker.ready .then(function(registration) { console.log('Service Worker Ready'); }); } SERVICE WORKER
INSTALL const CACHE_NAME = ‘DevUp’ // Version 0.6.5 self.addEventListener('install', e
=> { console.log('installing service worker!!') const timeStamp = Date.now(); e.waitUntil( caches.open(CACHE_NAME).then(cache => { return cache.addAll([ `/`, `/index.html`, `/json/data.json`, `/static/js/bundle.js` ]) .then(() => self.skipWaiting()); }) ); });
INSTALL const CACHE_NAME = ‘DevUp’ // Version 0.6.5 self.addEventListener('install', e
=> { console.log('installing service worker!!') const timeStamp = Date.now(); e.waitUntil( caches.open(CACHE_NAME).then(cache => { return cache.addAll([ `/`, `/index.html`, `/json/data.json`, `/static/js/bundle.js` ]) .then(() => self.skipWaiting()); }) ); });
INSTALL const CACHE_NAME = ‘DevUp' // Version 0.6.5 self.addEventListener('install', e
=> { console.log('installing service worker!!') const timeStamp = Date.now(); e.waitUntil( caches.open(CACHE_NAME).then(cache => { return cache.addAll([ `/`, `/index.html`, `/json/data.json`, `/static/js/bundle.js` ]) .then(() => self.skipWaiting()); }) ); });
ACTIVATE self.addEventListener('activate', event => { console.log('activating service worker'); event.waitUntil(self.clients.claim()); });
FETCH self.addEventListener('fetch', function(event) {…})
FETCH event.respondWith( caches.match(event.request) .then(function(response) { // Cache hit - return
response if (response) { return response; } var fetchRequest = event.request.clone(); return fetch(fetchRequest).then( function(response) { // Check if we received a valid response if(!response || response.status !== 200 || response.type !== 'basic'){ return response; } var responseToCache = response.clone(); caches.open(CACHE_NAME)
FETCH event.respondWith( caches.match(event.request) .then(function(response) { // Cache hit - return
response if (response) { return response; } var fetchRequest = event.request.clone(); return fetch(fetchRequest).then( function(response) { // Check if we received a valid response if(!response || response.status !== 200 || response.type !== 'basic'){ return response; } var responseToCache = response.clone(); caches.open(CACHE_NAME)
FETCH event.respondWith( caches.match(event.request) .then(function(response) { // Cache hit - return
response if (response) { return response; } var fetchRequest = event.request.clone(); return fetch(fetchRequest).then( function(response) { // Check if we received a valid response if(!response || response.status !== 200 || response.type !== 'basic'){ return response; } var responseToCache = response.clone(); caches.open(CACHE_NAME)
event.respondWith( caches.match(event.request) .then(function(response) { // Cache hit - return response
if (response) { return response; } var fetchRequest = event.request.clone(); return fetch(fetchRequest).then( function(response) { // Check if we received a valid response if(!response || response.status !== 200 || response.type !== 'basic'){ return response; } var responseToCache = response.clone(); caches.open(CACHE_NAME) FETCH
} var fetchRequest = event.request.clone(); return fetch(fetchRequest).then( function(response) { //
Check if we received a valid response if(!response || response.status !== 200 || response.type !== 'basic'){ return response; } var responseToCache = response.clone(); caches.open(CACHE_NAME) .then(function(cache) { cache.put(event.request, responseToCache); }); return response; } ); }) ); FETCH
} var fetchRequest = event.request.clone(); return fetch(fetchRequest).then( function(response) { //
Check if we received a valid response if(!response || response.status !== 200 || response.type !== 'basic'){ return response; } var responseToCache = response.clone(); caches.open(CACHE_NAME) .then(function(cache) { cache.put(event.request, responseToCache); }); return response; } ); }) ); FETCH
} var fetchRequest = event.request.clone(); return fetch(fetchRequest).then( function(response) { //
Check if we received a valid response if(!response || response.status !== 200 || response.type !== 'basic'){ return response; } var responseToCache = response.clone(); caches.open(CACHE_NAME) .then(function(cache) { cache.put(event.request, responseToCache); }); return response; } ); }) ); FETCH
} var fetchRequest = event.request.clone(); return fetch(fetchRequest).then( function(response) { //
Check if we received a valid response if(!response || response.status !== 200 || response.type !== 'basic'){ return response; } var responseToCache = response.clone(); caches.open(CACHE_NAME) .then(function(cache) { cache.put(event.request, responseToCache); }); return response; } ); }) ); FETCH
Demo
None
Manifest
A manifest describes your web page in an
INDEX.HTML <link rel="manifest" href="%PUBLIC_URL%/manifest.json">
MANIFEST { "short_name": "Library", "name": “DevUp Library Demo", "icons": [
{ "src": "book.png", "sizes": "192X192", "type": "image/png" } ], "start_url": "./index.html", "display": "standalone", "theme_color": "#000000", "background_color": "#ffffff" }
Demo
None
Let’s Deploy
None
Github Pages to the rescue
PACKAGE.JSON – ADDING GH-PAGES { "name": "library", "version": "0.1.0", "private":
true, "homepage": “https://jonathanfmills.github.io/DEVUPPWA”, "dependencies": { "gh-pages": "^1.1.0", … }, "scripts": { "predeploy": "npm run build", "deploy": "gh-pages -d build", } }
Demo
http://bit.ly/devuppwa
@ j o n a t h a n f
m i l l s #reactPWA P R O G R E S S I V E W E B A P P S W I T H R E A C T