SlideShare a Scribd company logo
1 of 43
Developing “Offline First” Web Apps
with Service Worker
GDG North Central Devfest, Abuja 2016
Auwal Muhammad
Samu
@auwalms_
Software Engineer,
SoftQuest System
Limited.
What are Offline First
Apps?
Use a Service Worker
`
Web server
Service worker
Client side proxy
(written in JavaScript)
Cache
Web server
Service Worker Life Cycle
Activated Error
Idle
Active Terminated
Install
Register
• Wakes up only when the OS
says
• Only responds to system
events
• Adds app-like lifecycle
to a page
is for the SECOND load.
Service Worker
Life Cycle of a Service Worker
Installing the Service Worker
2nd Page Load
activated
check for
update
Life Cycle of a Service Worker
Installing the Service Worker
Close Page
idle
terminated
activated
Life Cycle of a Service Worker
Updating a Service Worker
Load Page with Service Worker
activated
check for
update
Life Cycle of a Service Worker
Updating a Service Worker
Load Page with Service Worker
activated
check for
update
install
idle
Implementing a simple Service Worker
Activated Error
Idle
Active Terminated
Install
Register
Register the Service Worker
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);
});
}
Activated Error
Idle
Active Terminated
Install
Register
Add an install Event Handler
Add an install Event Handler
self.addEventListener('install', function(event) {
return self.skipWaiting();
});
Activated Error
Idle
Active Terminated
Install
Register
Pre-fetch the App Resources
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();
})
);
});
Activated Error
Idle
Active Terminated
Install
Register
Add an activate Event Handler
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();
});
Activated Error
Idle
Active Terminated
Install
Register
Not Done Yet...
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);
})
);
});
Activated Error
Idle
Active Terminated
Install
Register
Ready to Go!
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
Generic Fallback
Cache and Network Race
Offline First with Service Worker

More Related Content

What's hot

Micrometerでメトリクスを収集してAmazon CloudWatchで可視化
Micrometerでメトリクスを収集してAmazon CloudWatchで可視化Micrometerでメトリクスを収集してAmazon CloudWatchで可視化
Micrometerでメトリクスを収集してAmazon CloudWatchで可視化Ryosuke Uchitate
 
決済サービスのSpring Bootのバージョンを2系に上げた話
決済サービスのSpring Bootのバージョンを2系に上げた話決済サービスのSpring Bootのバージョンを2系に上げた話
決済サービスのSpring Bootのバージョンを2系に上げた話Ryosuke Uchitate
 
Spring Boot Actuator
Spring Boot ActuatorSpring Boot Actuator
Spring Boot ActuatorRowell Belen
 
Spring Boot and REST API
Spring Boot and REST APISpring Boot and REST API
Spring Boot and REST API07.pallav
 
ASP.NET Page Life Cycle
ASP.NET Page Life CycleASP.NET Page Life Cycle
ASP.NET Page Life CycleAbhishek Sur
 
PWA Roadshow Seoul - HTTPS
PWA Roadshow Seoul - HTTPSPWA Roadshow Seoul - HTTPS
PWA Roadshow Seoul - HTTPSChang W. Doh
 
Spring Booted, But... @JCConf 16', Taiwan
Spring Booted, But... @JCConf 16', TaiwanSpring Booted, But... @JCConf 16', Taiwan
Spring Booted, But... @JCConf 16', TaiwanPei-Tang Huang
 
Spring boot introduction
Spring boot introductionSpring boot introduction
Spring boot introductionRasheed Waraich
 
Gigigo Rails Workshop
Gigigo Rails WorkshopGigigo Rails Workshop
Gigigo Rails WorkshopAlex Rupérez
 
Spring Boot and Microservices
Spring Boot and MicroservicesSpring Boot and Microservices
Spring Boot and Microservicesseges
 
PWA Roadshow Korea - Service Worker
PWA Roadshow Korea - Service WorkerPWA Roadshow Korea - Service Worker
PWA Roadshow Korea - Service Workerjungkees
 
Introduction to ReactJS and Redux
Introduction to ReactJS and ReduxIntroduction to ReactJS and Redux
Introduction to ReactJS and ReduxBoris Dinkevich
 
[1D1]신개념 N스크린 웹 앱 프레임워크 PARS
[1D1]신개념 N스크린 웹 앱 프레임워크 PARS[1D1]신개념 N스크린 웹 앱 프레임워크 PARS
[1D1]신개념 N스크린 웹 앱 프레임워크 PARSNAVER D2
 
Maxim Salnikov - Service Worker: taking the best from the past experience for...
Maxim Salnikov - Service Worker: taking the best from the past experience for...Maxim Salnikov - Service Worker: taking the best from the past experience for...
Maxim Salnikov - Service Worker: taking the best from the past experience for...Codemotion
 

What's hot (20)

Micrometerでメトリクスを収集してAmazon CloudWatchで可視化
Micrometerでメトリクスを収集してAmazon CloudWatchで可視化Micrometerでメトリクスを収集してAmazon CloudWatchで可視化
Micrometerでメトリクスを収集してAmazon CloudWatchで可視化
 
決済サービスのSpring Bootのバージョンを2系に上げた話
決済サービスのSpring Bootのバージョンを2系に上げた話決済サービスのSpring Bootのバージョンを2系に上げた話
決済サービスのSpring Bootのバージョンを2系に上げた話
 
Spring Boot Actuator
Spring Boot ActuatorSpring Boot Actuator
Spring Boot Actuator
 
Spring Boot and REST API
Spring Boot and REST APISpring Boot and REST API
Spring Boot and REST API
 
ASP.NET Page Life Cycle
ASP.NET Page Life CycleASP.NET Page Life Cycle
ASP.NET Page Life Cycle
 
PWA Roadshow Seoul - HTTPS
PWA Roadshow Seoul - HTTPSPWA Roadshow Seoul - HTTPS
PWA Roadshow Seoul - HTTPS
 
Spring Booted, But... @JCConf 16', Taiwan
Spring Booted, But... @JCConf 16', TaiwanSpring Booted, But... @JCConf 16', Taiwan
Spring Booted, But... @JCConf 16', Taiwan
 
Spring boot introduction
Spring boot introductionSpring boot introduction
Spring boot introduction
 
Spring boot
Spring bootSpring boot
Spring boot
 
Advanced redux
Advanced reduxAdvanced redux
Advanced redux
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Grails plugin
Grails pluginGrails plugin
Grails plugin
 
Reduxing like a pro
Reduxing like a proReduxing like a pro
Reduxing like a pro
 
Gigigo Rails Workshop
Gigigo Rails WorkshopGigigo Rails Workshop
Gigigo Rails Workshop
 
Spring Boot and Microservices
Spring Boot and MicroservicesSpring Boot and Microservices
Spring Boot and Microservices
 
PWA Roadshow Korea - Service Worker
PWA Roadshow Korea - Service WorkerPWA Roadshow Korea - Service Worker
PWA Roadshow Korea - Service Worker
 
Introduction to ReactJS and Redux
Introduction to ReactJS and ReduxIntroduction to ReactJS and Redux
Introduction to ReactJS and Redux
 
[1D1]신개념 N스크린 웹 앱 프레임워크 PARS
[1D1]신개념 N스크린 웹 앱 프레임워크 PARS[1D1]신개념 N스크린 웹 앱 프레임워크 PARS
[1D1]신개념 N스크린 웹 앱 프레임워크 PARS
 
Spring Boot Tutorial
Spring Boot TutorialSpring Boot Tutorial
Spring Boot Tutorial
 
Maxim Salnikov - Service Worker: taking the best from the past experience for...
Maxim Salnikov - Service Worker: taking the best from the past experience for...Maxim Salnikov - Service Worker: taking the best from the past experience for...
Maxim Salnikov - Service Worker: taking the best from the past experience for...
 

Similar to Offline First with Service Worker

[1C1]Service Workers
[1C1]Service Workers[1C1]Service Workers
[1C1]Service WorkersNAVER D2
 
Building Progressive Web Apps for Windows devices
Building Progressive Web Apps for Windows devicesBuilding Progressive Web Apps for Windows devices
Building Progressive Web Apps for Windows devicesWindows Developer
 
Service workers and the role they play in modern day web apps
Service workers and the role they play in modern day web appsService workers and the role they play in modern day web apps
Service workers and the role they play in modern day web appsMukul Jain
 
"Service Worker: Let Your Web App Feel Like a Native "
"Service Worker: Let Your Web App Feel Like a Native ""Service Worker: Let Your Web App Feel Like a Native "
"Service Worker: Let Your Web App Feel Like a Native "FDConf
 
Service workers
Service workersService workers
Service workersjungkees
 
Sencha Roadshow 2017: Build Progressive Web Apps with Ext JS and Cmd
Sencha Roadshow 2017: Build Progressive Web Apps with Ext JS and Cmd Sencha Roadshow 2017: Build Progressive Web Apps with Ext JS and Cmd
Sencha Roadshow 2017: Build Progressive Web Apps with Ext JS and Cmd Sencha
 
Slide Deck - Shift Left Beyond App Performance Improvement at Gojek_.pptx
Slide Deck - Shift Left Beyond App Performance Improvement at Gojek_.pptxSlide Deck - Shift Left Beyond App Performance Improvement at Gojek_.pptx
Slide Deck - Shift Left Beyond App Performance Improvement at Gojek_.pptxraditya gumay
 
Service worker: discover the next web game changer
Service worker: discover the next web game changerService worker: discover the next web game changer
Service worker: discover the next web game changerSandro Paganotti
 
Bringing the open web and APIs to mobile devices with Firefox OS - Whisky W...
 	Bringing the open web and APIs to mobile devices with Firefox OS - Whisky W... 	Bringing the open web and APIs to mobile devices with Firefox OS - Whisky W...
Bringing the open web and APIs to mobile devices with Firefox OS - Whisky W...Robert Nyman
 
Building websites with Node.ACS
Building websites with Node.ACSBuilding websites with Node.ACS
Building websites with Node.ACSralcocer
 
Building websites with Node.ACS
Building websites with Node.ACSBuilding websites with Node.ACS
Building websites with Node.ACSRicardo Alcocer
 
JavaScript APIs - The Web is the Platform
JavaScript APIs - The Web is the PlatformJavaScript APIs - The Web is the Platform
JavaScript APIs - The Web is the PlatformRobert Nyman
 
Asynchronous Interfaces
Asynchronous InterfacesAsynchronous Interfaces
Asynchronous Interfacesmaccman
 
JSChannel 2017 - Service Workers and the Role they Play in modern day web-apps
JSChannel 2017 - Service Workers and the Role they Play in modern day web-appsJSChannel 2017 - Service Workers and the Role they Play in modern day web-apps
JSChannel 2017 - Service Workers and the Role they Play in modern day web-appsMukul Jain
 
Workboxで始める Service Worker
Workboxで始める Service WorkerWorkboxで始める Service Worker
Workboxで始める Service WorkerKazuyoshi Tsuchiya
 
Android & iOS Automation Using Appium
Android & iOS Automation Using AppiumAndroid & iOS Automation Using Appium
Android & iOS Automation Using AppiumMindfire Solutions
 
Introducing ASP.NET Core 2.0
Introducing ASP.NET Core 2.0Introducing ASP.NET Core 2.0
Introducing ASP.NET Core 2.0Steven Smith
 

Similar to Offline First with Service Worker (20)

[1C1]Service Workers
[1C1]Service Workers[1C1]Service Workers
[1C1]Service Workers
 
Building Progressive Web Apps for Windows devices
Building Progressive Web Apps for Windows devicesBuilding Progressive Web Apps for Windows devices
Building Progressive Web Apps for Windows devices
 
Service workers and the role they play in modern day web apps
Service workers and the role they play in modern day web appsService workers and the role they play in modern day web apps
Service workers and the role they play in modern day web apps
 
"Service Worker: Let Your Web App Feel Like a Native "
"Service Worker: Let Your Web App Feel Like a Native ""Service Worker: Let Your Web App Feel Like a Native "
"Service Worker: Let Your Web App Feel Like a Native "
 
Service workers
Service workersService workers
Service workers
 
Service workers
Service workersService workers
Service workers
 
Sencha Roadshow 2017: Build Progressive Web Apps with Ext JS and Cmd
Sencha Roadshow 2017: Build Progressive Web Apps with Ext JS and Cmd Sencha Roadshow 2017: Build Progressive Web Apps with Ext JS and Cmd
Sencha Roadshow 2017: Build Progressive Web Apps with Ext JS and Cmd
 
Slide Deck - Shift Left Beyond App Performance Improvement at Gojek_.pptx
Slide Deck - Shift Left Beyond App Performance Improvement at Gojek_.pptxSlide Deck - Shift Left Beyond App Performance Improvement at Gojek_.pptx
Slide Deck - Shift Left Beyond App Performance Improvement at Gojek_.pptx
 
Service worker: discover the next web game changer
Service worker: discover the next web game changerService worker: discover the next web game changer
Service worker: discover the next web game changer
 
Serverless Java on Kubernetes
Serverless Java on KubernetesServerless Java on Kubernetes
Serverless Java on Kubernetes
 
Bringing the open web and APIs to mobile devices with Firefox OS - Whisky W...
 	Bringing the open web and APIs to mobile devices with Firefox OS - Whisky W... 	Bringing the open web and APIs to mobile devices with Firefox OS - Whisky W...
Bringing the open web and APIs to mobile devices with Firefox OS - Whisky W...
 
Building websites with Node.ACS
Building websites with Node.ACSBuilding websites with Node.ACS
Building websites with Node.ACS
 
Building websites with Node.ACS
Building websites with Node.ACSBuilding websites with Node.ACS
Building websites with Node.ACS
 
JavaScript APIs - The Web is the Platform
JavaScript APIs - The Web is the PlatformJavaScript APIs - The Web is the Platform
JavaScript APIs - The Web is the Platform
 
Asynchronous Interfaces
Asynchronous InterfacesAsynchronous Interfaces
Asynchronous Interfaces
 
JSChannel 2017 - Service Workers and the Role they Play in modern day web-apps
JSChannel 2017 - Service Workers and the Role they Play in modern day web-appsJSChannel 2017 - Service Workers and the Role they Play in modern day web-apps
JSChannel 2017 - Service Workers and the Role they Play in modern day web-apps
 
Workboxで始める Service Worker
Workboxで始める Service WorkerWorkboxで始める Service Worker
Workboxで始める Service Worker
 
AWS CodeDeploy
AWS CodeDeployAWS CodeDeploy
AWS CodeDeploy
 
Android & iOS Automation Using Appium
Android & iOS Automation Using AppiumAndroid & iOS Automation Using Appium
Android & iOS Automation Using Appium
 
Introducing ASP.NET Core 2.0
Introducing ASP.NET Core 2.0Introducing ASP.NET Core 2.0
Introducing ASP.NET Core 2.0
 

Recently uploaded

Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 

Recently uploaded (20)

Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 

Offline First with Service Worker

  • 1. Developing “Offline First” Web Apps with Service Worker GDG North Central Devfest, Abuja 2016
  • 3. What are Offline First Apps?
  • 4.
  • 5. Use a Service Worker
  • 7. Service worker Client side proxy (written in JavaScript) Cache Web server
  • 8. Service Worker Life Cycle Activated Error Idle Active Terminated Install Register • Wakes up only when the OS says • Only responds to system events • Adds app-like lifecycle to a page
  • 9. is for the SECOND load. Service Worker
  • 10. Life Cycle of a Service Worker Installing the Service Worker 2nd Page Load activated check for update
  • 11. Life Cycle of a Service Worker Installing the Service Worker Close Page idle terminated activated
  • 12. Life Cycle of a Service Worker Updating a Service Worker Load Page with Service Worker activated check for update
  • 13. Life Cycle of a Service Worker Updating a Service Worker Load Page with Service Worker activated check for update install idle
  • 14. Implementing a simple Service Worker
  • 16. 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); }); }
  • 17. 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); }); }
  • 19. Add an install Event Handler self.addEventListener('install', function(event) { return self.skipWaiting(); });
  • 21. 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(); }) ); });
  • 22. 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(); }) ); });
  • 23. 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(); }) ); });
  • 24. 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(); }) ); });
  • 26. 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(); });
  • 27. 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(); });
  • 29.
  • 30. Add a fetch Event Handler self.addEventListener('fetch', function(e) { e.respondWith( caches.match(e.request).then(function(response) { return response || fetch(e.request); }) ); });
  • 31. Add a fetch Event Handler self.addEventListener('fetch', function(e) { e.respondWith( caches.match(e.request).then(function(response) { return response || fetch(e.request); }) ); });
  • 32. Add a fetch Event Handler self.addEventListener('fetch', function(e) { e.respondWith( caches.match(e.request).then(function(response) { return response || fetch(e.request); }) ); });
  • 33. Add a fetch Event Handler self.addEventListener('fetch', function(e) { e.respondWith( caches.match(e.request).then(function(response) { return response || fetch(e.request); }) ); });
  • 35. 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); }); }
  • 36. 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); }); }
  • 37. 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); }); }
  • 38. 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); }); }
  • 39. Caching strategies You are in control of the network
  • 40. Cache, Falling Back to Network

Editor's Notes

  1. Offline first app are actually online-offline apps. This apps have the capability of running during downtime
  2. No one wants to see this screen except if you are like me when am tired or got stucked by bugs.
  3. Once your site is being served over HTTPS you’re ready to build a Service Worker. Who here has heard of Service Workers? For anyone who hasn’t, let me explain…
  4. The traditional web model has been, when you type in an URL or select a bookmark, the browser goes to the network to fetch the page. If the network is [CLICK] down - you get the famous downasaur. But you don’t necessarily need to traverse the network every time.
  5. Instead you can use a service worker. A service worker is a JavaScript file which acts like a proxy sitting between your browser and the network. When a page registers a service worker, it adds a set of event handlers to respond to things like network requests and push messages. The SW also allows you to manage the cache and you can decide if a request should be served from the cache or fetched from the network. And because it's event based, the SW doesn't need to be in memory unless it's handling one of those events.
  6. I'll say it again, because I think it's important, a Service Worker doesn’t consume any system processing resources until it’s woken up to handle an event. In fact, even if the browser is closed, the OS can wake up a service worker. We're no longer limited to the model where an “app must be loaded in an active tab” to be useful. This is important because it introduces an app-like lifecycle for the web.
  7. On the topic of “Service Worker as a progressive enhancement”, it’s important to understand that the FIRST time you load the page, it’s still going to be loading from the network - the index page has already been retrieved from the network, of course, and the page’s resources will kick off downloading normally. The Service Worker will come into play on subsequent loads, not the first load. Though, there is one caveat to that, I'll cover that in a moment.
  8. When the page is reloaded, or you hit another page covered by the service worker, the service worker becomes activated, ready to handle all of its events. At the same time, [CLICK] the browser also makes an asynchronous request to the server to see if the service worker has changed since it was last retrieved.
  9. Once the service worker has handled all of the events, [CLICK] it goes to idle, and eventually it's terminated, ready to spin up again when any new events come in.
  10. Let's keep going with our previous example and see how a service worker gets updated. Since we've already been to the page, the service worker is already installed and is immediately activated. [CLICK] Then, just like before, the browser checks with the server to see if the service worker has changed, and this time, it has.
  11. This is an important point to remember as you're working on your own service workers. You may find yourself in situations where you have multiple service workers installed and waiting, because the original one, hasn't been terminated yet. There are ways to work around this but we’ll cover those a bit later.
  12. Enough theory, let's take a look at how we can implement our own service worker.
  13. The first step is registering the service worker
  14. In our index page we will place a small piece of logic to check for the presence of the service worker API in our browser, then…
  15. if it is available, we register the service worker by calling navigator.serviceWorker.register with a simple reference to the location of the service worker javascript file.
  16. Next, we need to handle the install event, which is fired after the service worker javascript file has been downloaded and parsed.
  17. Let's start with something basic. Remember earlier I mentioned that when a service worker is installed the first time, it doesn't take immediate control of the page? Well, there's a way around that. Calling self.skipWaiting tells the service worker you want it to skip waiting, and go right to work.
  18. We'll use the install event to pre-fetch the resources we need, and cache them in the local cache, ensuring that the files can be loaded instantly and reliably. In effect, this install event handler is your opportunity to have a fully scriptable install process, just like a native app; you have absolute control over what resources are pre-fetched and how they are cached.
  19. First, let's open up a cache object, referenced by cacheName.
  20. Then, we'll use cache.addAll to retrieve the resources we've listed in filesToCache and store them in our browser cache. In a real implementation, you should make sure that you catch any exceptions here. If one of the files were to fail while downloading, the entire event fails and the service worker wouldn't be activated.
  21. And finally, once everything has been added, we want to call self.skipWaiting, so that our service worker takes immediate control. This means “don’t wait for a reload to activate this new ServiceWorker.”
  22. There's one other thing I want to point out, we wrapped that whole code block in event.waitUntil. That makes sure that the service worker isn't terminated and won’t go idle while we're waiting for the embedded promise - the caching of resources - to complete.
  23. Once everything has been cached, and our service worker has been activated, it's a good idea to clean up the cache to remove any out-dated resources.
  24. There are plenty of ways to do this, but in this case, we iterate over the list of keys from the cache, then delete any caches that don't match the current cache name.
  25. And there's one more thing we need to do. By calling self.clients.claim, we tell the browser that we want THIS service worker to take control of all of the clients that it controls. That means we don't have to wait until any other service workers that are running terminate, we're ready to go immediately!
  26. But at this point if you were to go offline…
  27. …you would still get the dreaded offline dinosaur. But why? So far we’ve done a lot to pre-cache files but we haven’t added any handlers to deal with network fetch events. The default onfetch handler is still just hitting the network. So let’s change that.
  28. We’ll assume that every required resource for our app is already in the cache; but if it is not we'll just go out to the network to fetch it. When a network request is made from our web page our Service Worker wakes up and the `fetch` event is triggered.
  29. Next, we check to see if the requested resource is in the cache.
  30. If it is, we return the version from the cache.
  31. Otherwise, we request it from the network and return that.
  32. We now have a reliable experience that loads almost instantly. Our app will work whether we're online or offline, and it'll load extremely quickly because we've eliminated any potential network latency. Our last step is to let the page know that the service worker is now registered and ready to go. This is helpful if you want to indicate to the user that the page is offline capable.
  33. Earlier, I mentioned scopes. One of the cool things about a service worker is that you don't need to register it on every page. You only need to register it once, and any page within the scope will be handled by the service worker. The easiest way to define a scope is simply based on where the service worker is served from.
  34. I recommend that you serve your service worker from the server root, that means every resource requested will be handled by the service worker.
  35. If you put it in your scripts directory, only resources served from scripts will be handled by the service worker. In this case, unless the page registering the service worker is also in scripts, it won't be handled by the service worker. [CLICK] I did this my first time, and it SUCKED, so don't make the same mistake I made.
  36. Putting the service worker in your server root gives you the first crack at responding to any network requests, and helps to ensure your app is reliable and loads almost instantly.
  37. The important thing to understand about Service Worker is that you are in control of the network. You get to decide what is cached, how it is cached and how it should be returned to the user. In the code we’ve been walking through, our example used a simple cache-first strategy with network fallback to ensure that we had a consistent experience. But there are multiple caching strategies you might want to use, depending on your app scenario…
  38. The cache first with network fallback strategy we’ve laid out is pretty straightforward - always go to the cache first. If the request matches a cache entry, respond with that. Otherwise try to fetch the resource from the network. This option is good for resources that don't change, or have some other update mechanism. It will give you a very fast response - since objects come out of the cache directly - but it doesn’t update. On the negative side, if an item isn't in the cache, it's not automatically added after its retrieved from the network.
  39. You could also do a generic fallback solution where a request is made first to the cache, then the network, and if both of them fail, a second request is made to the cache for a generic page.
  40. Or have the cache and the network race…
  41. To wrap up. I want to add that we’ve been really excited to see incredible momentum on progressive web apps across the globe. This is just a sample of folks who are shipping or actively working on PWAs and new web APIs.