SlideShare uma empresa Scribd logo
1 de 54
Offline-first web apps 
Matt Andrews, Financial Times 
@andrewsmatt, mattandre.ws
• HTML5 
• Offline-first 
• Sideways-swipe-enabled 
• Add-to-home-screen-able 
• iOS 
• Web App
• HTML5 
• Offline-first 
• Sideways-swipe-enabled 
• Add-to-home-screen-able 
• iOS 
• Android 
• Web App
• HTML5 
• Offline-first 
• Sideways-swipe-enabled 
• Add-to-home-screen-able 
• iOS 
• Android 
• Windows 
• Web App
• HTML5 
• Offline-first 
• Sideways-swipe-enabled 
• Add-to-home-screen-able 
• iOS 
• Android 
• Windows 
• Firefox 
• Web App
• HTML5 
• Offline-first 
• Sideways-swipe-enabled 
• Add-to-home-screen-able 
• iOS 
• Android 
• Windows 
• Firefox 
• ALL THE THINGS 
• Web App
What’s so important 
about offline?
Internet Connections 
• Not just on or off 
• On can sometimes mean off 
• Slow can be worse than off
So why is FT app so slow?
AppCache 
CACHE MANIFEST 
/my-font.ttf 
/my-styles.css 
! 
! 
<DOCTYPE html> 
<html manifest="mywebapp.manifest">
AppCache 
CACHE MANIFEST 
/my-font.ttf 
/my-styles.css 
! 
NETWORK: 
* 
<DOCTYPE html> 
<html manifest="mywebapp.manifest">
AppCache Hacks 
• Varying the response of every page based on whether a cookie is set 
(hack needs to be added to our CDN as well as back end) 
• Returning an HTTP error on the manifest request when that cookie is 
not set; 
• Created an iframe to load a page that loads the manifest rather 
than referencing it directly. 
• Without the NETWORK: * hack in your AppCache manifest you will 
break all non-offline'd resources. 
• Putting all our API methods on a path starting with /api so that our 
FALLBACK doesn’t interfere with ajax requests. 
• Returning different Cache-Control headers on Internet Explorer 10+.
@andrewsmatt
Service Workers 
+ Fetch + Caches
Fetch API 
XMLHttpRequest revamped
var xhr = new XMLHttpRequest(); 
xhr.onreadystatechange = function() { 
if (xhr.readyState === 4) { 
if (xhr.status === 200) { 
alert(xhr.responseText); 
} else { 
alert('There was a problem.'); 
} 
} 
}; 
xhr.ontimeout = function() { 
alert('There was a problem.'); 
}; 
xhr.open('GET', 'http://a.b/c.html'); 
with XMLHttpRequest
fetch('http://a.b/c.html') 
.then(function(response) { 
return response.text(); // can be .json, .blob 
}) 
.then(function(text) { 
alert(text); 
}) 
.catch(function() { 
alert('There was a problem.'); 
}); 
with Fetch API
Using Fetch 
Native within Service Workers only 
Browser-only polyfill:- 
github.com/github/fetch 
‘Isomorphic’ Fetch Polyfill that works in 
Node and in the browser via 
Browserify:- 
bit.ly/iso-fetch
Cache API 
Caching that speaks JavaScript
caches.open(‘my-app’) 
.then(function(cache) { 
return cache 
.addAll([ 
‘/my-styles.css’, 
‘/my-font.ttf’ 
]); 
}); 
Pre-Cache URLs
caches.match(new Request(‘/my-styles.css’)) 
.then(function(response) { 
// got back /my-styles.css 
}); 
‘Fetch’ URLs from Cache
caches.open(‘my-app’) 
.then(function(cache) { 
return cache.put(‘/my-fake-endpoint’, 
new Response(‘Hello!’)); 
}); 
Put ‘fake’ responses into the Cache
Put ‘fake’ responses into the Cache 
WARNING: the difference between ‘add’ & ’put’ is 
different to the difference between IndexedDB’s 
‘add’ & ‘put’ 
add put 
IndexedDB INSERT INSERT OR UPDATE 
Service Worker 
Caches 
INSERT OR UPDATE INSERT OR UPDATE
caches.open(‘my-app’) 
.then(function(cache) { 
return cache.keys(); 
}) 
.then(function(keys) { 
return cache.addAll(keys); 
}); 
Update content in the Cache 
WARNING: This will ‘break’ any ‘fake requests’ that have 
been ‘put’ted 
WARNING: The Service Worker Cache is in addition to 
the regular HTTP Cache.
Service Workers
<DOCTYPE html> 
<html> 
<head><title>mattandre.ws</title></head> 
<body> 
<h1>My offline website</h1> 
<script> 
navigator.serviceWorker.register(‘./sw.js’) 
</script> 
</body> 
</html>
sw.js:- 
this.oninstall = function(event) { 
// prepare website to work offline, 
// e.g. cache resources 
}; 
this.onfetch = function(event) { 
// listen to, manipulate and/or respond 
// requests from your app 
};
sw.js:- 
this.oninstall = function(event) { 
var promise = caches.open(‘my-app’) 
.then(function(cache) { 
return cache 
.addAll([ 
‘/my-styles.css’, 
‘/my-font.ttf’ 
]); 
}); 
! 
event.waitUntil(promise); 
};
<DOCTYPE html> 
<html> 
<head><title>mattandre.ws</title></head> 
<body> 
<h1>My offline website</h1> 
<script> 
navigator.serviceWorker.register(‘./sw.js’) 
.then(function() { 
// installed 
}) 
.catch(function() { 
// didn’t install :( 
}); 
</script> 
</body> 
</html>
sw.js:- 
this.onfetch = function(event) { 
var promise; 
promise = caches.match(event.request) 
.catch(function() { 
return fetch(event.request); 
}); 
event.respondWith(promise); 
};
Service Worker 
Gotchas
chrome://flags#enable-experimental-web-platform-features
bit.ly/isserviceworkerready
No Caches 
The Service Worker Cache API does 
not work yet but a Polyfill exists that 
uses IndexedDB underneath:- 
bit.ly/caches-polyfill
Storage Limits 
• Every origin (protocol+domain+port) gets an 
allowance of offline storage, typically 50mb 
• Allowance shared between IndexedDB & 
Service Workers 
• Each origin only has access to data in its 
caches & databases.
Some JavaScript APIs are not 
available in Service Worker:- 
• LocalStorage 
• Synchronous ajax
https
You can use Service Workers to 
make offline-first websites… 
…or just to make normal 
websites faster.
Beyond Service 
Worker
Advanced Offline 
• Simple Caches not always enough 
• Use IndexedDB for more structured 
data, e.g. user preferences, bookmarks 
• Don’t use WebSQL it’s deprecated, use 
the polyfill. bit.ly/idbpolyfill
• Origins can have multiple IndexedDB 
databases 
• Each database can have multiple ‘object 
stores’ (like SQL tables) 
• An object store must have at least one 
index – IDB is NoSQL – can only be queried 
by pre-defined indexes 
• No free text search
function databaseOpen() {! 
! return new Promise(function(resolve, reject) {! 
! ! var version = 1;! 
! ! var request = indexedDB.open('todos', version);! 
! ! request.onupgradeneeded = function(e) {! 
! ! ! db = e.target.result;! 
! ! ! e.target.transaction.onerror = reject;! 
! ! ! db.createObjectStore('todo', {! 
! ! ! ! keyPath: '_id'! 
! ! ! });! 
! ! };! 
! ! request.onsuccess = function(e) {! 
! ! ! db = e.target.result;! 
! ! ! resolve();! 
! ! };! 
! ! request.onerror = reject;! 
! });! 
} raw javascript
Highly recommend 
Dexie.org, a Promise-based 
IndexedDB library
function databaseOpen() {! 
! var db = new Dexie('todos');! 
! db.version(1).stores({ todo: '_id' });! 
! return db.open();! 
} 
with Dexie.org
Summary 
• Service Worker is coming so get ready:- 
https, Promises, Caches Polyfill … 
• Use the Fetch API in your applications today 
bit.ly/iso-fetch / github.com/github/fetch 
• Want to use IDB? Use dexie.org. Want to support 
WebSQL? Use the polyfill bit.ly/idbpolyfill. 
• I’ve written tutorials on how to use all the HTML5 offline 
tech available for free here:- 
bit.ly/offline-workshop
Thanks! 
• Open Source:- 
github.com/ftlabs 
FastClick, Polyfill.io, DOM Delegate, Ellipsis, & more 
• Jobs:- 
labs.ft.com/jobs 
• Me:- 
@andrewsmatt / mattandre.ws

Mais conteúdo relacionado

Mais procurados

Primefaces Nextgen Lju
Primefaces Nextgen LjuPrimefaces Nextgen Lju
Primefaces Nextgen Lju
Skills Matter
 

Mais procurados (20)

Containers & Dependency in Ember.js
Containers & Dependency in Ember.jsContainers & Dependency in Ember.js
Containers & Dependency in Ember.js
 
Service worker - Offline Web
Service worker - Offline WebService worker - Offline Web
Service worker - Offline Web
 
Choosing a Javascript Framework
Choosing a Javascript FrameworkChoosing a Javascript Framework
Choosing a Javascript Framework
 
Service worker API
Service worker APIService worker API
Service worker API
 
Ember and containers
Ember and containersEmber and containers
Ember and containers
 
Primefaces Nextgen Lju
Primefaces Nextgen LjuPrimefaces Nextgen Lju
Primefaces Nextgen Lju
 
Making Django and NoSQL Play Nice
Making Django and NoSQL Play NiceMaking Django and NoSQL Play Nice
Making Django and NoSQL Play Nice
 
Good karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with KarmaGood karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with Karma
 
Unobtrusive JavaScript
Unobtrusive JavaScriptUnobtrusive JavaScript
Unobtrusive JavaScript
 
Maintainable JavaScript 2012
Maintainable JavaScript 2012Maintainable JavaScript 2012
Maintainable JavaScript 2012
 
What happens in laravel 4 bootstraping
What happens in laravel 4 bootstrapingWhat happens in laravel 4 bootstraping
What happens in laravel 4 bootstraping
 
Beyond DOM Manipulations: Building Stateful Modules with Events and Promises
Beyond DOM Manipulations: Building Stateful Modules with Events and PromisesBeyond DOM Manipulations: Building Stateful Modules with Events and Promises
Beyond DOM Manipulations: Building Stateful Modules with Events and Promises
 
Jsp
JspJsp
Jsp
 
Chef at WebMD
Chef at WebMDChef at WebMD
Chef at WebMD
 
Testing Ember Apps: Managing Dependency
Testing Ember Apps: Managing DependencyTesting Ember Apps: Managing Dependency
Testing Ember Apps: Managing Dependency
 
Introduction to VueJS & The WordPress REST API
Introduction to VueJS & The WordPress REST APIIntroduction to VueJS & The WordPress REST API
Introduction to VueJS & The WordPress REST API
 
Integrating React.js Into a PHP Application
Integrating React.js Into a PHP ApplicationIntegrating React.js Into a PHP Application
Integrating React.js Into a PHP Application
 
RSpec
RSpecRSpec
RSpec
 
Excellent
ExcellentExcellent
Excellent
 
WordCamp Ann Arbor 2015 Introduction to Backbone + WP REST API
WordCamp Ann Arbor 2015 Introduction to Backbone + WP REST APIWordCamp Ann Arbor 2015 Introduction to Backbone + WP REST API
WordCamp Ann Arbor 2015 Introduction to Backbone + WP REST API
 

Destaque

Mjd presentation1 (4)
Mjd presentation1 (4)Mjd presentation1 (4)
Mjd presentation1 (4)
t7260678
 
CHACOAL EVAPORATIVE COOLING TECHNOLOGY FOR STORAGE OF DWARF GER MARGLOBE TOMA...
CHACOAL EVAPORATIVE COOLING TECHNOLOGY FOR STORAGE OF DWARF GER MARGLOBE TOMA...CHACOAL EVAPORATIVE COOLING TECHNOLOGY FOR STORAGE OF DWARF GER MARGLOBE TOMA...
CHACOAL EVAPORATIVE COOLING TECHNOLOGY FOR STORAGE OF DWARF GER MARGLOBE TOMA...
International Journal of Technical Research & Application
 
Biologia (1)
Biologia (1)Biologia (1)
Biologia (1)
carlos582
 
Trabajo informatoca RODRIGO
Trabajo informatoca RODRIGOTrabajo informatoca RODRIGO
Trabajo informatoca RODRIGO
laurita1999
 
Sinfonia en blanco
Sinfonia en blancoSinfonia en blanco
Sinfonia en blanco
Nat Di
 

Destaque (20)

Venues, banquet halls, party halls in e venuebooking
Venues, banquet halls, party halls in e venuebookingVenues, banquet halls, party halls in e venuebooking
Venues, banquet halls, party halls in e venuebooking
 
Mjd presentation1 (4)
Mjd presentation1 (4)Mjd presentation1 (4)
Mjd presentation1 (4)
 
Digital marketing-training-institute
Digital marketing-training-instituteDigital marketing-training-institute
Digital marketing-training-institute
 
CHACOAL EVAPORATIVE COOLING TECHNOLOGY FOR STORAGE OF DWARF GER MARGLOBE TOMA...
CHACOAL EVAPORATIVE COOLING TECHNOLOGY FOR STORAGE OF DWARF GER MARGLOBE TOMA...CHACOAL EVAPORATIVE COOLING TECHNOLOGY FOR STORAGE OF DWARF GER MARGLOBE TOMA...
CHACOAL EVAPORATIVE COOLING TECHNOLOGY FOR STORAGE OF DWARF GER MARGLOBE TOMA...
 
остесинт14
остесинт14остесинт14
остесинт14
 
MB Slides (15 March)
MB Slides (15 March)MB Slides (15 March)
MB Slides (15 March)
 
Derechos de autor
Derechos de autorDerechos de autor
Derechos de autor
 
Tiene algún sentido el bautismo hoy
Tiene algún sentido el bautismo hoyTiene algún sentido el bautismo hoy
Tiene algún sentido el bautismo hoy
 
Teorias administrativas
Teorias administrativasTeorias administrativas
Teorias administrativas
 
Hult Impact Challenge - IBM Watson Seismic
Hult Impact Challenge - IBM Watson SeismicHult Impact Challenge - IBM Watson Seismic
Hult Impact Challenge - IBM Watson Seismic
 
Biologia (1)
Biologia (1)Biologia (1)
Biologia (1)
 
Trello et Basecamp: deux outils de gestion de projet pour les nuls
Trello et Basecamp: deux outils de gestion de projet pour les nulsTrello et Basecamp: deux outils de gestion de projet pour les nuls
Trello et Basecamp: deux outils de gestion de projet pour les nuls
 
стихи
стихистихи
стихи
 
The Complete Guide to Planning Online Communications for Your Church
The Complete Guide to Planning Online Communications for Your ChurchThe Complete Guide to Planning Online Communications for Your Church
The Complete Guide to Planning Online Communications for Your Church
 
Rúbrica evaluar blog
Rúbrica evaluar blogRúbrica evaluar blog
Rúbrica evaluar blog
 
Offline first, the painless way
Offline first, the painless wayOffline first, the painless way
Offline first, the painless way
 
Trabajo informatoca RODRIGO
Trabajo informatoca RODRIGOTrabajo informatoca RODRIGO
Trabajo informatoca RODRIGO
 
Sinfonia en blanco
Sinfonia en blancoSinfonia en blanco
Sinfonia en blanco
 
ข้อสอบการงานอาชีพและเทคโนโลยี O-net ม.6
ข้อสอบการงานอาชีพและเทคโนโลยี O-net ม.6ข้อสอบการงานอาชีพและเทคโนโลยี O-net ม.6
ข้อสอบการงานอาชีพและเทคโนโลยี O-net ม.6
 
World Usability Day 2014 - David Lai — Stakeholders!
World Usability Day 2014 - David Lai — Stakeholders!World Usability Day 2014 - David Lai — Stakeholders!
World Usability Day 2014 - David Lai — Stakeholders!
 

Semelhante a Velocity EU 2014 — Offline-first web apps

An Introduction to Tornado
An Introduction to TornadoAn Introduction to Tornado
An Introduction to Tornado
Gavin Roy
 
Javascript MVC & Backbone Tips & Tricks
Javascript MVC & Backbone Tips & TricksJavascript MVC & Backbone Tips & Tricks
Javascript MVC & Backbone Tips & Tricks
Hjörtur Hilmarsson
 
HTML5: huh, what is it good for?
HTML5: huh, what is it good for?HTML5: huh, what is it good for?
HTML5: huh, what is it good for?
Remy Sharp
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applications
Tom Croucher
 
Intro to node.js - Ran Mizrahi (28/8/14)
Intro to node.js - Ran Mizrahi (28/8/14)Intro to node.js - Ran Mizrahi (28/8/14)
Intro to node.js - Ran Mizrahi (28/8/14)
Ran Mizrahi
 
Introduction to Node.js
Introduction to Node.jsIntroduction to Node.js
Introduction to Node.js
Richard Lee
 

Semelhante a Velocity EU 2014 — Offline-first web apps (20)

Primefaces Nextgen Lju
Primefaces Nextgen LjuPrimefaces Nextgen Lju
Primefaces Nextgen Lju
 
Express Presentation
Express PresentationExpress Presentation
Express Presentation
 
An Introduction to Tornado
An Introduction to TornadoAn Introduction to Tornado
An Introduction to Tornado
 
API Days Paris - Automatic Testing of (RESTful) API Documentation
API Days Paris - Automatic Testing of (RESTful) API DocumentationAPI Days Paris - Automatic Testing of (RESTful) API Documentation
API Days Paris - Automatic Testing of (RESTful) API Documentation
 
Javascript MVC & Backbone Tips & Tricks
Javascript MVC & Backbone Tips & TricksJavascript MVC & Backbone Tips & Tricks
Javascript MVC & Backbone Tips & Tricks
 
Rich Portlet Development in uPortal
Rich Portlet Development in uPortalRich Portlet Development in uPortal
Rich Portlet Development in uPortal
 
HTML5: huh, what is it good for?
HTML5: huh, what is it good for?HTML5: huh, what is it good for?
HTML5: huh, what is it good for?
 
Javascript first-class citizenery
Javascript first-class citizeneryJavascript first-class citizenery
Javascript first-class citizenery
 
Introduction to Vert.x
Introduction to Vert.xIntroduction to Vert.x
Introduction to Vert.x
 
Taking your Web App for a walk
Taking your Web App for a walkTaking your Web App for a walk
Taking your Web App for a walk
 
Attractive HTML5~開発者の視点から~
Attractive HTML5~開発者の視点から~Attractive HTML5~開発者の視点から~
Attractive HTML5~開発者の視点から~
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applications
 
HTML5 tutorial: canvas, offfline & sockets
HTML5 tutorial: canvas, offfline & socketsHTML5 tutorial: canvas, offfline & sockets
HTML5 tutorial: canvas, offfline & sockets
 
Html5 and web technology update
Html5 and web technology updateHtml5 and web technology update
Html5 and web technology update
 
Intro to node.js - Ran Mizrahi (27/8/2014)
Intro to node.js - Ran Mizrahi (27/8/2014)Intro to node.js - Ran Mizrahi (27/8/2014)
Intro to node.js - Ran Mizrahi (27/8/2014)
 
Intro to node.js - Ran Mizrahi (28/8/14)
Intro to node.js - Ran Mizrahi (28/8/14)Intro to node.js - Ran Mizrahi (28/8/14)
Intro to node.js - Ran Mizrahi (28/8/14)
 
Introduction to Node.js
Introduction to Node.jsIntroduction to Node.js
Introduction to Node.js
 
Nordic APIs - Automatic Testing of (RESTful) API Documentation
Nordic APIs - Automatic Testing of (RESTful) API DocumentationNordic APIs - Automatic Testing of (RESTful) API Documentation
Nordic APIs - Automatic Testing of (RESTful) API Documentation
 
JavaScript performance patterns
JavaScript performance patternsJavaScript performance patterns
JavaScript performance patterns
 
Using and scaling Rack and Rack-based middleware
Using and scaling Rack and Rack-based middlewareUsing and scaling Rack and Rack-based middleware
Using and scaling Rack and Rack-based middleware
 

Último

+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 

Último (20)

Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu SubbuApidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 

Velocity EU 2014 — Offline-first web apps

  • 1. Offline-first web apps Matt Andrews, Financial Times @andrewsmatt, mattandre.ws
  • 2.
  • 3.
  • 4. • HTML5 • Offline-first • Sideways-swipe-enabled • Add-to-home-screen-able • iOS • Web App
  • 5. • HTML5 • Offline-first • Sideways-swipe-enabled • Add-to-home-screen-able • iOS • Android • Web App
  • 6. • HTML5 • Offline-first • Sideways-swipe-enabled • Add-to-home-screen-able • iOS • Android • Windows • Web App
  • 7. • HTML5 • Offline-first • Sideways-swipe-enabled • Add-to-home-screen-able • iOS • Android • Windows • Firefox • Web App
  • 8. • HTML5 • Offline-first • Sideways-swipe-enabled • Add-to-home-screen-able • iOS • Android • Windows • Firefox • ALL THE THINGS • Web App
  • 9. What’s so important about offline?
  • 10.
  • 11.
  • 12.
  • 13. Internet Connections • Not just on or off • On can sometimes mean off • Slow can be worse than off
  • 14.
  • 15. So why is FT app so slow?
  • 16. AppCache CACHE MANIFEST /my-font.ttf /my-styles.css ! ! <DOCTYPE html> <html manifest="mywebapp.manifest">
  • 17. AppCache CACHE MANIFEST /my-font.ttf /my-styles.css ! NETWORK: * <DOCTYPE html> <html manifest="mywebapp.manifest">
  • 18. AppCache Hacks • Varying the response of every page based on whether a cookie is set (hack needs to be added to our CDN as well as back end) • Returning an HTTP error on the manifest request when that cookie is not set; • Created an iframe to load a page that loads the manifest rather than referencing it directly. • Without the NETWORK: * hack in your AppCache manifest you will break all non-offline'd resources. • Putting all our API methods on a path starting with /api so that our FALLBACK doesn’t interfere with ajax requests. • Returning different Cache-Control headers on Internet Explorer 10+.
  • 20.
  • 21. Service Workers + Fetch + Caches
  • 23. var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { if (xhr.readyState === 4) { if (xhr.status === 200) { alert(xhr.responseText); } else { alert('There was a problem.'); } } }; xhr.ontimeout = function() { alert('There was a problem.'); }; xhr.open('GET', 'http://a.b/c.html'); with XMLHttpRequest
  • 24. fetch('http://a.b/c.html') .then(function(response) { return response.text(); // can be .json, .blob }) .then(function(text) { alert(text); }) .catch(function() { alert('There was a problem.'); }); with Fetch API
  • 25. Using Fetch Native within Service Workers only Browser-only polyfill:- github.com/github/fetch ‘Isomorphic’ Fetch Polyfill that works in Node and in the browser via Browserify:- bit.ly/iso-fetch
  • 26. Cache API Caching that speaks JavaScript
  • 27. caches.open(‘my-app’) .then(function(cache) { return cache .addAll([ ‘/my-styles.css’, ‘/my-font.ttf’ ]); }); Pre-Cache URLs
  • 28. caches.match(new Request(‘/my-styles.css’)) .then(function(response) { // got back /my-styles.css }); ‘Fetch’ URLs from Cache
  • 29. caches.open(‘my-app’) .then(function(cache) { return cache.put(‘/my-fake-endpoint’, new Response(‘Hello!’)); }); Put ‘fake’ responses into the Cache
  • 30. Put ‘fake’ responses into the Cache WARNING: the difference between ‘add’ & ’put’ is different to the difference between IndexedDB’s ‘add’ & ‘put’ add put IndexedDB INSERT INSERT OR UPDATE Service Worker Caches INSERT OR UPDATE INSERT OR UPDATE
  • 31. caches.open(‘my-app’) .then(function(cache) { return cache.keys(); }) .then(function(keys) { return cache.addAll(keys); }); Update content in the Cache WARNING: This will ‘break’ any ‘fake requests’ that have been ‘put’ted WARNING: The Service Worker Cache is in addition to the regular HTTP Cache.
  • 33. <DOCTYPE html> <html> <head><title>mattandre.ws</title></head> <body> <h1>My offline website</h1> <script> navigator.serviceWorker.register(‘./sw.js’) </script> </body> </html>
  • 34. sw.js:- this.oninstall = function(event) { // prepare website to work offline, // e.g. cache resources }; this.onfetch = function(event) { // listen to, manipulate and/or respond // requests from your app };
  • 35.
  • 36. sw.js:- this.oninstall = function(event) { var promise = caches.open(‘my-app’) .then(function(cache) { return cache .addAll([ ‘/my-styles.css’, ‘/my-font.ttf’ ]); }); ! event.waitUntil(promise); };
  • 37. <DOCTYPE html> <html> <head><title>mattandre.ws</title></head> <body> <h1>My offline website</h1> <script> navigator.serviceWorker.register(‘./sw.js’) .then(function() { // installed }) .catch(function() { // didn’t install :( }); </script> </body> </html>
  • 38. sw.js:- this.onfetch = function(event) { var promise; promise = caches.match(event.request) .catch(function() { return fetch(event.request); }); event.respondWith(promise); };
  • 42. No Caches The Service Worker Cache API does not work yet but a Polyfill exists that uses IndexedDB underneath:- bit.ly/caches-polyfill
  • 43. Storage Limits • Every origin (protocol+domain+port) gets an allowance of offline storage, typically 50mb • Allowance shared between IndexedDB & Service Workers • Each origin only has access to data in its caches & databases.
  • 44. Some JavaScript APIs are not available in Service Worker:- • LocalStorage • Synchronous ajax
  • 45. https
  • 46. You can use Service Workers to make offline-first websites… …or just to make normal websites faster.
  • 48. Advanced Offline • Simple Caches not always enough • Use IndexedDB for more structured data, e.g. user preferences, bookmarks • Don’t use WebSQL it’s deprecated, use the polyfill. bit.ly/idbpolyfill
  • 49. • Origins can have multiple IndexedDB databases • Each database can have multiple ‘object stores’ (like SQL tables) • An object store must have at least one index – IDB is NoSQL – can only be queried by pre-defined indexes • No free text search
  • 50. function databaseOpen() {! ! return new Promise(function(resolve, reject) {! ! ! var version = 1;! ! ! var request = indexedDB.open('todos', version);! ! ! request.onupgradeneeded = function(e) {! ! ! ! db = e.target.result;! ! ! ! e.target.transaction.onerror = reject;! ! ! ! db.createObjectStore('todo', {! ! ! ! ! keyPath: '_id'! ! ! ! });! ! ! };! ! ! request.onsuccess = function(e) {! ! ! ! db = e.target.result;! ! ! ! resolve();! ! ! };! ! ! request.onerror = reject;! ! });! } raw javascript
  • 51. Highly recommend Dexie.org, a Promise-based IndexedDB library
  • 52. function databaseOpen() {! ! var db = new Dexie('todos');! ! db.version(1).stores({ todo: '_id' });! ! return db.open();! } with Dexie.org
  • 53. Summary • Service Worker is coming so get ready:- https, Promises, Caches Polyfill … • Use the Fetch API in your applications today bit.ly/iso-fetch / github.com/github/fetch • Want to use IDB? Use dexie.org. Want to support WebSQL? Use the polyfill bit.ly/idbpolyfill. • I’ve written tutorials on how to use all the HTML5 offline tech available for free here:- bit.ly/offline-workshop
  • 54. Thanks! • Open Source:- github.com/ftlabs FastClick, Polyfill.io, DOM Delegate, Ellipsis, & more • Jobs:- labs.ft.com/jobs • Me:- @andrewsmatt / mattandre.ws