SlideShare a Scribd company logo
@thisNatasha
ServiceWorkers
on vacay...
Natasha Rooney
@thisNatasha
GSMA Web Technologist
W3C WebMob Co-Chair
www.w3.org/Mobile/IG/
@thisNatasha
Going on Vacation
@thisNatasha
I use apps, but I want the web!
@thisNatasha
I want the web!
@thisNatasha
ServiceWorkers
@thisNatasha
ServiceWorker eh?
Offline Cache Worker
source: Chang W. Doh
@thisNatasha
ServiceWorker eh?
Offline Cache Worker
Navigation Controller
source: Chang W. Doh
@thisNatasha
ServiceWorker eh?
Offline Cache Worker
Navigation Controller
Event Manager
source: Chang W. Doh
@thisNatasha
Offline Cache Worker
Navigation Controller
Event Manager
ServiceWorker eh?
source: Chang W. Doh
@thisNatasha
ServiceWorker eh?
source: Chang W. Doh
Control request / response flow
Load a cached copy of a resource
@thisNatasha
ServiceWorker eh?
source: Chang W. Doh
Push &
Background
Sync
Cache Control
/ Custom
Response
Faster Load
Time!
Control request / response flow
Load a cached copy of a resource
@thisNatasha
ServiceWorker eh?
source: Chang W. Doh
Control request / response flow
Load a cached copy of a resource
Push &
Background
Sync
Cache Control
/ Custom
Response
Faster Load
Time!
@thisNatasha
Ok fine, but what is it?
Worker: script
separate from the
webpage
@thisNatasha
Ok fine, but what is it?
Worker: script
separate from the
webpageDifferent
Lifecycle
@thisNatasha
Ok fine, but what is it?
Worker: script
separate from the
webpageDifferent
Lifecycle
Terminated when
not in use
@thisNatasha
Ok fine, but what is it?
Worker: script
separate from the
webpageDifferent
Lifecycle
“In terms of network control, it acts like a
proxy server sitting on the client, you get to
decide what to do on a request-by-request
basis. You can use this to make stuff work
faster, offline, or build new features.”
Jake Archibald
Terminated when
not in use
@thisNatasha
Lifecycle
Installs
Activates
Waits
Network fetch
detection
Terminated
source: html5rocks
@thisNatasha
Two APIs one interface representing a proxy for a value
not necessarily known when that thing is created… (um, Promises)
Fetch
Gives
ServiceWorkers
the powers to
manage network
requests and
return responses
for resources
https://fetch.spec.whatwg.org/
https://slightlyoff.github.io/ServiceWorke
r/spec/service_worker/index.html#cach
e-objects
Cache
Save fetched
responses, return
these responses
later, not part of
HTTP cache
+ Promises
@thisNatasha
Setup
@thisNatasha
Setup
@thisNatasha
Setup
40
@thisNatasha
@thisNatasha
@thisNatasha
Installation
Running [Status,
Start, Stop]
Sync / Push
States:
@thisNatasha
Installation
Running [Status,
Start, Stop]
Sync / Push
States:
@thisNatasha
Let’s do this.
@thisNatasha
Register
Register your ServiceWorker in your main JavaScript file.
// filename: app.js
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js').then(function(registration) {
// Registration was successful
console.log('ServiceWorker registration successful,
scope: ', registration.scope);
}).catch(function(err) {
// registration failed
console.log('ServiceWorker registration failed: ', err);
});
}
source: html5rocks
@thisNatasha
Register
Register your ServiceWorker in your main JavaScript file.
// filename: app.js
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js').then(function(registration) {
// Registration was successful
console.log('ServiceWorker registration successful,
scope: ', registration.scope);
}).catch(function(err) {
// registration failed
console.log('ServiceWorker registration failed: ', err);
});
}
source: html5rocks
app.js
@thisNatasha
Register
Register your ServiceWorker in your main JavaScript file.
// filename: app.js
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js').then(function(registration) {
// Registration was successful
console.log('ServiceWorker registration successful,
scope: ', registration.scope);
}).catch(function(err) {
// registration failed
console.log('ServiceWorker registration failed: ', err);
});
}
source: html5rocks
SW location
@thisNatasha
Register
Register your ServiceWorker in your main JavaScript file.
// filename: app.js
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js').then(function(registration) {
// Registration was successful
console.log('ServiceWorker registration successful,
scope: ', registration.scope);
}).catch(function(err) {
// registration failed
console.log('ServiceWorker registration failed: ', err);
});
}
source: html5rocks
Browser does
the rest!
@thisNatasha
Create sw.js
Or whatever you want to call your ServiceWorker javascript file...
// filename: sw.js
TIP: sw.js goes
in the root of
the domain
@thisNatasha
Install
Give assets you want to run offline
// filename: sw.js
// The files we want to cache
var shellcache = 'shell-v1';
var urlsToCache = [
'/',
'/app/css/dist/bootstrap.min.css',
'/app/js/dist/angular.min.js',
'/app/js/dist/jquery-1.11.2.min.js',
'/app/js/dist/bootstrap.min.js'
];
// INSTALL
self.addEventListener('install', function(event) {
// Perform install steps
event.waitUntil(
caches.open(shellcache) //our cache!
.then(function(cache) {
console.log('Opened cache');
return cache.addAll(urlsToCache); //pass all our urls!
})
);
});
@thisNatasha
// filename: sw.js
// The files we want to cache
var shellcache = 'shell-v1';
var urlsToCache = [
'/',
'/app/css/dist/bootstrap.min.css',
'/app/js/dist/angular.min.js',
'/app/js/dist/jquery-1.11.2.min.js',
'/app/js/dist/bootstrap.min.js'
];
// INSTALL
self.addEventListener('install', function(event) {
// Perform install steps
event.waitUntil(
caches.open(shellcache) //our cache!
.then(function(cache) {
console.log('Opened cache');
return cache.addAll(urlsToCache); //pass all our urls!
})
);
});
Install
Give assets you want to run offline
Setup and
populate
caches!
@thisNatasha
// filename: sw.js
// The files we want to cache
var shellcache = 'shell-v1';
var urlsToCache = [
'/',
'/app/css/dist/bootstrap.min.css',
'/app/js/dist/angular.min.js',
'/app/js/dist/jquery-1.11.2.min.js',
'/app/js/dist/bootstrap.min.js'
];
// INSTALL
self.addEventListener('install', function(event) {
// Perform install steps
event.waitUntil(
caches.open(shellcache) //our cache!
.then(function(cache) {
console.log('Opened cache');
return cache.addAll(urlsToCache); //pass all our urls!
})
);
});
Install
opened
cache!
Give assets you want to run offline
@thisNatasha
// filename: sw.js
// The files we want to cache
var shellcache = 'shell-v1';
var urlsToCache = [
'/',
'/app/css/dist/bootstrap.min.css',
'/app/js/dist/angular.min.js',
'/app/js/dist/jquery-1.11.2.min.js',
'/app/js/dist/bootstrap.min.js'
];
// INSTALL
self.addEventListener('install', function(event) {
// Perform install steps
event.waitUntil(
caches.open(shellcache) //our cache!
.then(function(cache) {
console.log('Opened cache');
return cache.addAll(urlsToCache); //pass all our urls!
})
);
});
Install
pass in array
of files
Give assets you want to run offline
@thisNatasha
// filename: sw.js
// The files we want to cache
var shellcache = 'shell-v1';
var urlsToCache = [
'/',
'/app/css/dist/bootstrap.min.css',
'/app/js/dist/angular.min.js',
'/app/js/dist/jquery-1.11.2.min.js',
'/app/js/dist/bootstrap.min.js'
];
// INSTALL
self.addEventListener('install', function(event) {
// Perform install steps
event.waitUntil(
caches.open(shellcache) //our cache!
.then(function(cache) {
console.log('Opened cache');
return cache.addAll(urlsToCache); //pass all our urls!
})
);
});
Install
TIP: everything
must cache at
install to be
successful!
Give assets you want to run offline
@thisNatasha
@thisNatasha
TIP: Use an
incognito
window to test
your app!
@thisNatasha
Fetch
Detect network fetches
// detect fetches
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request)
.then(function(response) {
…
})
);
});
1st Visit: Install
ServiceWorker
Later visits +
navigation:
worker kicks in!
@thisNatasha
Fetch
// detect fetches
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request)
.then(function(response) {
…
})
);
});
Worker will
receive “fetch”
events
Detect network fetches
@thisNatasha
Fetch
// detect fetches
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request)
.then(function(response) {
…
})
);
});
Worker will
receive “fetch”
events
fetch API allows
us to respond!
Detect network fetches
@thisNatasha
// detect fetches
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request)
.then(function(response) {
…
})
);
});
Fetch
Worker will
receive “fetch”
events
Manual response,
Network fetch, or
cached resouce!
Detect network fetches
@thisNatasha
Fetch
// detect fetches
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request)
.then(function(response) {
…
})
);
});
Worker will
receive “fetch”
events
gives info
about request
Detect network fetches
@thisNatasha
// sw.js
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request)
.then(function(response) {
if (response) {
return response; // cache hit! return response
}
// IMPORTANT: Clone the request.
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;
}
// IMPORTANT: Clone the response.
var responseToCache = response.clone();
caches.open(CACHE_NAME)
.then(function(cache) {
cache.put(event.request, responseToCache);
Caching
Detected fetches, return match if so or get from network as fallback
pass promise
caches.match
@thisNatasha
// sw.js
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request)
.then(function(response) {
if (response) {
return response; // cache hit! return response
}
// IMPORTANT: Clone the request.
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;
}
// IMPORTANT: Clone the response.
var responseToCache = response.clone();
caches.open(CACHE_NAME)
.then(function(cache) {
cache.put(event.request, responseToCache);
Caching
hmmm, any
matches in my
caches?
Detected fetches, return match if so or get from network as fallback
@thisNatasha
Caching
// sw.js
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request)
.then(function(response) {
if (response) {
return response; // cache hit! return response
}
// IMPORTANT: Clone the request.
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;
}
// IMPORTANT: Clone the response.
var responseToCache = response.clone();
caches.open(CACHE_NAME)
.then(function(cache) {
cache.put(event.request, responseToCache);
Got it! Awesome,
so return it!
Detected fetches, return match if so or get from network as fallback
@thisNatasha
Caching
// sw.js
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request)
.then(function(response) {
if (response) {
return response; // cache hit! return response
}
// IMPORTANT: Clone the request.
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;
}
// IMPORTANT: Clone the response.
var responseToCache = response.clone();
caches.open(CACHE_NAME)
.then(function(cache) {
cache.put(event.request, responseToCache);
Aw nothing in
cache, get from
network
Detected fetches, return match if so or get from network as fallback
@thisNatasha
Caching
Got it from the network? Why not add to the cache?
// sw.js
return fetch(fetchRequest).then(
function(response) {
// Check if we received a valid response
if(!response || response.status !== 200 || response.type !== 'basic') {
return response;
}
// IMPORTANT: Clone the response. A response is a stream
// and because we want the browser to consume the response
// as well as the cache consuming the response, we need
// to clone it so we have 2 stream.
var responseToCache = response.clone();
caches.open(CACHE_NAME)
.then(function(cache) {
cache.put(event.request, responseToCache);
});
return response;
}
);
})
);
});
@thisNatasha
Caching
Got it from the network? Why not add to the cache?
// sw.js
return fetch(fetchRequest).then(
function(response) {
// Check if we received a valid response
if(!response || response.status !== 200
|| response.type !== 'basic') {
return response;
}
// IMPORTANT: Clone the response. A response is a stream
// and because we want the browser to consume the response
// as well as the cache consuming the response, we need
// to clone it so we have 2 stream.
var responseToCache = response.clone();
caches.open(CACHE_NAME)
.then(function(cache) {
cache.put(event.request, responseToCache);
});
return response;
}
);
})
);
check response
@thisNatasha
Caching
Got it from the network? Why not add to the cache?
// sw.js
return fetch(fetchRequest).then(
function(response) {
// Check if we received a valid response
if(!response || response.status !== 200
|| response.type !== 'basic') {
return response;
}
// IMPORTANT: Clone the response. A response is a stream
// and because we want the browser to consume the response
// as well as the cache consuming the response, we need
// to clone it so we have 2 stream.
var responseToCache = response.clone();
caches.open(CACHE_NAME)
.then(function(cache) {
cache.put(event.request, responseToCache);
});
return response;
}
);
})
);
clone response
@thisNatasha
Caching
Got it from the network? Why not add to the cache?
// sw.js
return fetch(fetchRequest).then(
function(response) {
// Check if we received a valid response
if(!response || response.status !== 200
|| response.type !== 'basic') {
return response;
}
// IMPORTANT: Clone the response. A response is a stream
// and because we want the browser to consume the response
// as well as the cache consuming the response, we need
// to clone it so we have 2 stream.
var responseToCache = response.clone();
caches.open(CACHE_NAME)
.then(function(cache) {
cache.put(event.request, responseToCache);
});
return response;
}
);
})
);
add to cache
@thisNatasha
Update
Updating your ServiceWorker
// sw.js
self.addEventListener('activate', function(event) {
//var cacheWhitelist = ['shell-v1', 'blog-posts-cache-v1'];
var cacheWhitelist = ['shell-v1'];
event.waitUntil(
caches.keys().then(function(cacheNames) {
return Promise.all(
cacheNames.map(function(cacheName) {
if (cacheWhitelist.indexOf(cacheName) === -1) {
console.log('deleting: ' + cacheName);
return caches.delete(cacheName);
}
})
);
})
);
});
@thisNatasha
Update
Updating your ServiceWorker
// sw.js
self.addEventListener('activate', function(event) {
//var cacheWhitelist = ['shell-v1', 'blog-posts-cache-v1'];
var cacheWhitelist = ['shell-v1'];
event.waitUntil(
caches.keys().then(function(cacheNames) {
return Promise.all(
cacheNames.map(function(cacheName) {
if (cacheWhitelist.indexOf(cacheName) === -1) {
console.log('deleting: ' + cacheName);
return caches.delete(cacheName);
}
})
);
})
);
});
Edit and save
me
@thisNatasha
Update
Updating your ServiceWorker
// sw.js
self.addEventListener('activate', function(event) {
//var cacheWhitelist = ['shell-v1', 'blog-posts-cache-v1'];
var cacheWhitelist = ['shell-v1'];
event.waitUntil(
caches.keys().then(function(cacheNames) {
return Promise.all(
cacheNames.map(function(cacheName) {
if (cacheWhitelist.indexOf(cacheName) === -1) {
console.log('deleting: ' + cacheName);
return caches.delete(cacheName);
}
})
);
})
);
});
Edit and save
me
TIP: completely
close the
application!
@thisNatasha
Update
// sw.js
self.addEventListener('activate', function(event) {
//var cacheWhitelist = ['shell-v1', 'blog-posts-cache-v1'];
var cacheWhitelist = ['shell-v1'];
event.waitUntil(
caches.keys().then(function(cacheNames) {
return Promise.all(
cacheNames.map(function(cacheName) {
if (cacheWhitelist.indexOf(cacheName) === -1) {
console.log('deleting: ' + cacheName);
return caches.delete(cacheName);
}
})
);
})
);
});
Updating your ServiceWorker
Open app and
new SW should
kick in!
@thisNatasha
Update
Check caches need deleting or keeping
// sw.js
self.addEventListener('activate', function(event) {
//var cacheWhitelist = ['shell-v1', 'blog-posts-cache-v1'];
var cacheWhitelist = ['shell-v1'];
event.waitUntil(
caches.keys().then(function(cacheNames) {
return Promise.all(
cacheNames.map(function(cacheName) {
if (cacheWhitelist.indexOf(cacheName) === -1) {
console.log('deleting: ' + cacheName);
return caches.delete(cacheName);
}
})
);
})
);
});
Let’s do some
cache
management!
activate
callback
source: html5rocks
@thisNatasha
Update
Check caches need deleting or keeping
// sw.js
self.addEventListener('activate', function(event) {
var cacheWhitelist = ['shell-v1', 'blog-posts-cache-v1'];
event.waitUntil(
caches.keys().then(function(cacheNames) {
return Promise.all(
cacheNames.map(function(cacheName) {
if (cacheWhitelist.indexOf(cacheName) === -1) {
console.log('deleting: ' + cacheName);
return caches.delete(cacheName);
}
})
);
})
);
});
Let’s do some
cache
management!
defined in
install step
source: html5rocks
@thisNatasha
Update
Check caches need deleting or keeping
// sw.js
self.addEventListener('activate', function(event) {
var cacheWhitelist = ['shell-v1', 'blog-posts-cache-v1'];
event.waitUntil(
caches.keys().then(function(cacheNames) {
return Promise.all(
cacheNames.map(function(cacheName) {
if (cacheWhitelist.indexOf(cacheName) === -1) {
console.log('deleting: ' + cacheName);
return caches.delete(cacheName);
}
})
);
})
);
});
Let’s do some
cache
management!
loop through
and delete!
source: html5rocks
@thisNatasha
Cool Other Stuff!
What more can I do?
Push / Background Sync
Mess around with fallbacks
Pass in weird and wonderful
responses!
@thisNatasha
Ok I see how this
works, anything else I
should know?
TIP: Github
pages are
served over
HTTPS
@thisNatasha
[1] ServiceWorkers
mandate HTTPS
TIP: Github
pages are
served over
HTTPS
@thisNatasha
[2] So, can we
use ServiceWorkers
today?
@thisNatasha
New Questions
http://caniuse.com/#feat=serviceworkers
@thisNatasha
New Questions
https://jakearchibald.github.io/isserviceworkerready/
@thisNatasha
How Can I Help?
@thisNatasha
https://github.com/w3c-webmob/ServiceWorkersDemos
@thisNatasha
https://code.google.com/p/chromium/issues/
@thisNatasha
http://discourse.specifiction.org/
@thisNatasha
New Questions
Super new! What else do we need to know!?
How does this scale?
Does SW improve
performance?
How complex does
development become?
@thisNatasha
Some things we couldn’t cover...
[1] Extensible Web Manifesto
[2] Impacted APIs
@thisNatasha
Info and Links
Info and Links
@thisNatasha
ありがとう!
Natasha Rooney
@thisNatasha
GSMA Web Technologist
W3C WebMob Co-Chair
www.w3.org/Mobile/IG/
Thanks to:
Matt Gaunt & Jake Archibald for their previous
written work on ServiceWorker!

More Related Content

What's hot

Service Worker Presentation
Service Worker PresentationService Worker Presentation
Service Worker Presentation
Kyle Dorman
 
Real World Lessons in Progressive Web Application & Service Worker Caching
Real World Lessons in Progressive Web Application & Service Worker CachingReal World Lessons in Progressive Web Application & Service Worker Caching
Real World Lessons in Progressive Web Application & Service Worker Caching
Chris Love
 
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
Robert Nyman
 
Instant and offline apps with Service Worker
Instant and offline apps with Service WorkerInstant and offline apps with Service Worker
Instant and offline apps with Service Worker
Chang W. Doh
 
The Peanut Butter Cup of Web-dev: Plack and single page web apps
The Peanut Butter Cup of Web-dev: Plack and single page web appsThe Peanut Butter Cup of Web-dev: Plack and single page web apps
The Peanut Butter Cup of Web-dev: Plack and single page web apps
John Anderson
 
Cool like a Frontend Developer: Grunt, RequireJS, Bower and other Tools
Cool like a Frontend Developer: Grunt, RequireJS, Bower and other ToolsCool like a Frontend Developer: Grunt, RequireJS, Bower and other Tools
Cool like a Frontend Developer: Grunt, RequireJS, Bower and other Tools
Ryan Weaver
 
PWA 應用 - 實現網站離線瀏覽
PWA 應用 - 實現網站離線瀏覽PWA 應用 - 實現網站離線瀏覽
PWA 應用 - 實現網站離線瀏覽
Anna Su
 
Automated release management with team city & octopusdeploy - NDC 2013
Automated release management with team city & octopusdeploy - NDC 2013Automated release management with team city & octopusdeploy - NDC 2013
Automated release management with team city & octopusdeploy - NDC 2013
Kristoffer Deinoff
 
Spout
SpoutSpout
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
Sandro Paganotti
 
Spring Booted, But... @JCConf 16', Taiwan
Spring Booted, But... @JCConf 16', TaiwanSpring Booted, But... @JCConf 16', Taiwan
Spring Booted, But... @JCConf 16', Taiwan
Pei-Tang Huang
 
What's new in Rails 4
What's new in Rails 4What's new in Rails 4
What's new in Rails 4
Fabio Akita
 
React & The Art of Managing Complexity
React &  The Art of Managing ComplexityReact &  The Art of Managing Complexity
React & The Art of Managing Complexity
Ryan Anklam
 
Docker Demo @ IuK Seminar
Docker Demo @ IuK SeminarDocker Demo @ IuK Seminar
Docker Demo @ IuK Seminar
Martin Scharm
 
Building Offline Ready and Installable Web App
Building Offline Ready and Installable Web AppBuilding Offline Ready and Installable Web App
Building Offline Ready and Installable Web App
Muhammad Samu
 
"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
 
Django for IoT: From hackathon to production (DjangoCon US)
Django for IoT: From hackathon to production (DjangoCon US)Django for IoT: From hackathon to production (DjangoCon US)
Django for IoT: From hackathon to production (DjangoCon US)
Anna Schneider
 
Selenium sandwich-3: Being where you aren't.
Selenium sandwich-3: Being where you aren't.Selenium sandwich-3: Being where you aren't.
Selenium sandwich-3: Being where you aren't.
Workhorse Computing
 
Puppet Camp London Fall 2015 - Service Discovery and Puppet
Puppet Camp London Fall 2015 - Service Discovery and PuppetPuppet Camp London Fall 2015 - Service Discovery and Puppet
Puppet Camp London Fall 2015 - Service Discovery and Puppet
Marc Cluet
 

What's hot (19)

Service Worker Presentation
Service Worker PresentationService Worker Presentation
Service Worker Presentation
 
Real World Lessons in Progressive Web Application & Service Worker Caching
Real World Lessons in Progressive Web Application & Service Worker CachingReal World Lessons in Progressive Web Application & Service Worker Caching
Real World Lessons in Progressive Web Application & Service Worker Caching
 
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
 
Instant and offline apps with Service Worker
Instant and offline apps with Service WorkerInstant and offline apps with Service Worker
Instant and offline apps with Service Worker
 
The Peanut Butter Cup of Web-dev: Plack and single page web apps
The Peanut Butter Cup of Web-dev: Plack and single page web appsThe Peanut Butter Cup of Web-dev: Plack and single page web apps
The Peanut Butter Cup of Web-dev: Plack and single page web apps
 
Cool like a Frontend Developer: Grunt, RequireJS, Bower and other Tools
Cool like a Frontend Developer: Grunt, RequireJS, Bower and other ToolsCool like a Frontend Developer: Grunt, RequireJS, Bower and other Tools
Cool like a Frontend Developer: Grunt, RequireJS, Bower and other Tools
 
PWA 應用 - 實現網站離線瀏覽
PWA 應用 - 實現網站離線瀏覽PWA 應用 - 實現網站離線瀏覽
PWA 應用 - 實現網站離線瀏覽
 
Automated release management with team city & octopusdeploy - NDC 2013
Automated release management with team city & octopusdeploy - NDC 2013Automated release management with team city & octopusdeploy - NDC 2013
Automated release management with team city & octopusdeploy - NDC 2013
 
Spout
SpoutSpout
Spout
 
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
 
Spring Booted, But... @JCConf 16', Taiwan
Spring Booted, But... @JCConf 16', TaiwanSpring Booted, But... @JCConf 16', Taiwan
Spring Booted, But... @JCConf 16', Taiwan
 
What's new in Rails 4
What's new in Rails 4What's new in Rails 4
What's new in Rails 4
 
React & The Art of Managing Complexity
React &  The Art of Managing ComplexityReact &  The Art of Managing Complexity
React & The Art of Managing Complexity
 
Docker Demo @ IuK Seminar
Docker Demo @ IuK SeminarDocker Demo @ IuK Seminar
Docker Demo @ IuK Seminar
 
Building Offline Ready and Installable Web App
Building Offline Ready and Installable Web AppBuilding Offline Ready and Installable Web App
Building Offline Ready and Installable Web App
 
"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 "
 
Django for IoT: From hackathon to production (DjangoCon US)
Django for IoT: From hackathon to production (DjangoCon US)Django for IoT: From hackathon to production (DjangoCon US)
Django for IoT: From hackathon to production (DjangoCon US)
 
Selenium sandwich-3: Being where you aren't.
Selenium sandwich-3: Being where you aren't.Selenium sandwich-3: Being where you aren't.
Selenium sandwich-3: Being where you aren't.
 
Puppet Camp London Fall 2015 - Service Discovery and Puppet
Puppet Camp London Fall 2015 - Service Discovery and PuppetPuppet Camp London Fall 2015 - Service Discovery and Puppet
Puppet Camp London Fall 2015 - Service Discovery and Puppet
 

Similar to JQuery UK Service Workers Talk

PWA Roadshow Korea - Service Worker
PWA Roadshow Korea - Service WorkerPWA Roadshow Korea - Service Worker
PWA Roadshow Korea - Service Worker
jungkees
 
Progressive Web Apps 101
Progressive Web Apps 101Progressive Web Apps 101
Progressive Web Apps 101
Muhammad Samu
 
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
 
HTML5 tutorial: canvas, offfline & sockets
HTML5 tutorial: canvas, offfline & socketsHTML5 tutorial: canvas, offfline & sockets
HTML5 tutorial: canvas, offfline & sockets
Remy Sharp
 
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
Mukul Jain
 
ServiceWorker: New game changer is coming!
ServiceWorker: New game changer is coming!ServiceWorker: New game changer is coming!
ServiceWorker: New game changer is coming!
Chang W. Doh
 
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
Windows Developer
 
Zero-config JavaScript apps with RaveJS -- SVCC fall 2014
Zero-config JavaScript apps with RaveJS -- SVCC fall 2014Zero-config JavaScript apps with RaveJS -- SVCC fall 2014
Zero-config JavaScript apps with RaveJS -- SVCC fall 2014
John Hann
 
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
 
Taking Web Applications Offline
Taking Web Applications OfflineTaking Web Applications Offline
Taking Web Applications Offline
Matt Casto
 
What happens in laravel 4 bootstraping
What happens in laravel 4 bootstrapingWhat happens in laravel 4 bootstraping
What happens in laravel 4 bootstraping
Jace Ju
 
Spine.js
Spine.jsSpine.js
Spine.js
wearefractal
 
Running Node.js in Production using Passenger
Running Node.js in Production using PassengerRunning Node.js in Production using Passenger
Running Node.js in Production using Passenger
davidchubbs
 
BlackBerry DevCon 2011 - PhoneGap and WebWorks
BlackBerry DevCon 2011 - PhoneGap and WebWorksBlackBerry DevCon 2011 - PhoneGap and WebWorks
BlackBerry DevCon 2011 - PhoneGap and WebWorks
mwbrooks
 
Building websites with Node.ACS
Building websites with Node.ACSBuilding websites with Node.ACS
Building websites with Node.ACS
ralcocer
 
Building websites with Node.ACS
Building websites with Node.ACSBuilding websites with Node.ACS
Building websites with Node.ACS
Ricardo Alcocer
 
Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node js
Francois Zaninotto
 
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
 
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
 
Building Web Apps with Express
Building Web Apps with ExpressBuilding Web Apps with Express
Building Web Apps with Express
Aaron Stannard
 

Similar to JQuery UK Service Workers Talk (20)

PWA Roadshow Korea - Service Worker
PWA Roadshow Korea - Service WorkerPWA Roadshow Korea - Service Worker
PWA Roadshow Korea - Service Worker
 
Progressive Web Apps 101
Progressive Web Apps 101Progressive Web Apps 101
Progressive Web Apps 101
 
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?
 
HTML5 tutorial: canvas, offfline & sockets
HTML5 tutorial: canvas, offfline & socketsHTML5 tutorial: canvas, offfline & sockets
HTML5 tutorial: canvas, offfline & sockets
 
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
 
ServiceWorker: New game changer is coming!
ServiceWorker: New game changer is coming!ServiceWorker: New game changer is coming!
ServiceWorker: New game changer is coming!
 
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
 
Zero-config JavaScript apps with RaveJS -- SVCC fall 2014
Zero-config JavaScript apps with RaveJS -- SVCC fall 2014Zero-config JavaScript apps with RaveJS -- SVCC fall 2014
Zero-config JavaScript apps with RaveJS -- SVCC fall 2014
 
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...
 
Taking Web Applications Offline
Taking Web Applications OfflineTaking Web Applications Offline
Taking Web Applications Offline
 
What happens in laravel 4 bootstraping
What happens in laravel 4 bootstrapingWhat happens in laravel 4 bootstraping
What happens in laravel 4 bootstraping
 
Spine.js
Spine.jsSpine.js
Spine.js
 
Running Node.js in Production using Passenger
Running Node.js in Production using PassengerRunning Node.js in Production using Passenger
Running Node.js in Production using Passenger
 
BlackBerry DevCon 2011 - PhoneGap and WebWorks
BlackBerry DevCon 2011 - PhoneGap and WebWorksBlackBerry DevCon 2011 - PhoneGap and WebWorks
BlackBerry DevCon 2011 - PhoneGap and WebWorks
 
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
 
Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node js
 
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...
 
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
 
Building Web Apps with Express
Building Web Apps with ExpressBuilding Web Apps with Express
Building Web Apps with Express
 

More from Natasha Rooney

MARNEW at IETF 94
MARNEW at IETF 94MARNEW at IETF 94
MARNEW at IETF 94
Natasha Rooney
 
Web Authentication: a Future Without Passwords?
Web Authentication: a Future Without Passwords?Web Authentication: a Future Without Passwords?
Web Authentication: a Future Without Passwords?
Natasha Rooney
 
WebAppSec Updates from W3C
WebAppSec Updates from W3CWebAppSec Updates from W3C
WebAppSec Updates from W3C
Natasha Rooney
 
STV Voting System Explained
STV Voting System ExplainedSTV Voting System Explained
STV Voting System Explained
Natasha Rooney
 
TCP and Mobile Networks Turbulent Relationship
TCP and Mobile Networks Turbulent RelationshipTCP and Mobile Networks Turbulent Relationship
TCP and Mobile Networks Turbulent Relationship
Natasha Rooney
 
Solving HTTP Problems With Code and Protocols
Solving HTTP Problems With Code and ProtocolsSolving HTTP Problems With Code and Protocols
Solving HTTP Problems With Code and Protocols
Natasha Rooney
 
TLS Perf: from three to zero in one spec
TLS Perf:  from three to zero in one specTLS Perf:  from three to zero in one spec
TLS Perf: from three to zero in one spec
Natasha Rooney
 
Evolving HTTP and making things QUIC
Evolving HTTP and making things QUICEvolving HTTP and making things QUIC
Evolving HTTP and making things QUIC
Natasha Rooney
 
JQuery UK February 2015: Service Workers On Vacay
JQuery UK February 2015: Service Workers On VacayJQuery UK February 2015: Service Workers On Vacay
JQuery UK February 2015: Service Workers On Vacay
Natasha Rooney
 
GSMA in W3C
GSMA in W3CGSMA in W3C
GSMA in W3C
Natasha Rooney
 
Making it Work Offline: Current & Future Offline APIs for Web Apps
Making it Work Offline: Current & Future Offline APIs for Web AppsMaking it Work Offline: Current & Future Offline APIs for Web Apps
Making it Work Offline: Current & Future Offline APIs for Web Apps
Natasha Rooney
 
FirefoxOS Meetup - Updates on Offline in HTML5 Web Apps
FirefoxOS Meetup - Updates on Offline in HTML5 Web AppsFirefoxOS Meetup - Updates on Offline in HTML5 Web Apps
FirefoxOS Meetup - Updates on Offline in HTML5 Web Apps
Natasha Rooney
 
Updates on Offline: “My AppCache won’t come back” and “ServiceWorker Tricks ...
Updates on Offline: “My AppCache won’t come back” and  “ServiceWorker Tricks ...Updates on Offline: “My AppCache won’t come back” and  “ServiceWorker Tricks ...
Updates on Offline: “My AppCache won’t come back” and “ServiceWorker Tricks ...
Natasha Rooney
 

More from Natasha Rooney (13)

MARNEW at IETF 94
MARNEW at IETF 94MARNEW at IETF 94
MARNEW at IETF 94
 
Web Authentication: a Future Without Passwords?
Web Authentication: a Future Without Passwords?Web Authentication: a Future Without Passwords?
Web Authentication: a Future Without Passwords?
 
WebAppSec Updates from W3C
WebAppSec Updates from W3CWebAppSec Updates from W3C
WebAppSec Updates from W3C
 
STV Voting System Explained
STV Voting System ExplainedSTV Voting System Explained
STV Voting System Explained
 
TCP and Mobile Networks Turbulent Relationship
TCP and Mobile Networks Turbulent RelationshipTCP and Mobile Networks Turbulent Relationship
TCP and Mobile Networks Turbulent Relationship
 
Solving HTTP Problems With Code and Protocols
Solving HTTP Problems With Code and ProtocolsSolving HTTP Problems With Code and Protocols
Solving HTTP Problems With Code and Protocols
 
TLS Perf: from three to zero in one spec
TLS Perf:  from three to zero in one specTLS Perf:  from three to zero in one spec
TLS Perf: from three to zero in one spec
 
Evolving HTTP and making things QUIC
Evolving HTTP and making things QUICEvolving HTTP and making things QUIC
Evolving HTTP and making things QUIC
 
JQuery UK February 2015: Service Workers On Vacay
JQuery UK February 2015: Service Workers On VacayJQuery UK February 2015: Service Workers On Vacay
JQuery UK February 2015: Service Workers On Vacay
 
GSMA in W3C
GSMA in W3CGSMA in W3C
GSMA in W3C
 
Making it Work Offline: Current & Future Offline APIs for Web Apps
Making it Work Offline: Current & Future Offline APIs for Web AppsMaking it Work Offline: Current & Future Offline APIs for Web Apps
Making it Work Offline: Current & Future Offline APIs for Web Apps
 
FirefoxOS Meetup - Updates on Offline in HTML5 Web Apps
FirefoxOS Meetup - Updates on Offline in HTML5 Web AppsFirefoxOS Meetup - Updates on Offline in HTML5 Web Apps
FirefoxOS Meetup - Updates on Offline in HTML5 Web Apps
 
Updates on Offline: “My AppCache won’t come back” and “ServiceWorker Tricks ...
Updates on Offline: “My AppCache won’t come back” and  “ServiceWorker Tricks ...Updates on Offline: “My AppCache won’t come back” and  “ServiceWorker Tricks ...
Updates on Offline: “My AppCache won’t come back” and “ServiceWorker Tricks ...
 

Recently uploaded

Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
Ana-Maria Mihalceanu
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Albert Hoitingh
 
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
名前 です男
 
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy SurveyTrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc
 
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdfUni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems S.M.S.A.
 
Full-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalizationFull-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalization
Zilliz
 
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with SlackLet's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
shyamraj55
 
Presentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of GermanyPresentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of Germany
innovationoecd
 
Data structures and Algorithms in Python.pdf
Data structures and Algorithms in Python.pdfData structures and Algorithms in Python.pdf
Data structures and Algorithms in Python.pdf
TIPNGVN2
 
A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...
sonjaschweigert1
 
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
Neo4j
 
Climate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing DaysClimate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing Days
Kari Kakkonen
 
20 Comprehensive Checklist of Designing and Developing a Website
20 Comprehensive Checklist of Designing and Developing a Website20 Comprehensive Checklist of Designing and Developing a Website
20 Comprehensive Checklist of Designing and Developing a Website
Pixlogix Infotech
 
How to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptxHow to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptx
danishmna97
 
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
SOFTTECHHUB
 
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
Neo4j
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
20240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 202420240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 2024
Matthew Sinclair
 
Pushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 daysPushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 days
Adtran
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
Matthew Sinclair
 

Recently uploaded (20)

Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
 
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
 
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy SurveyTrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy Survey
 
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdfUni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdf
 
Full-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalizationFull-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalization
 
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with SlackLet's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
 
Presentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of GermanyPresentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of Germany
 
Data structures and Algorithms in Python.pdf
Data structures and Algorithms in Python.pdfData structures and Algorithms in Python.pdf
Data structures and Algorithms in Python.pdf
 
A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...
 
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
 
Climate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing DaysClimate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing Days
 
20 Comprehensive Checklist of Designing and Developing a Website
20 Comprehensive Checklist of Designing and Developing a Website20 Comprehensive Checklist of Designing and Developing a Website
20 Comprehensive Checklist of Designing and Developing a Website
 
How to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptxHow to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptx
 
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
 
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
20240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 202420240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 2024
 
Pushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 daysPushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 days
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
 

JQuery UK Service Workers Talk

  • 1. @thisNatasha ServiceWorkers on vacay... Natasha Rooney @thisNatasha GSMA Web Technologist W3C WebMob Co-Chair www.w3.org/Mobile/IG/
  • 3. @thisNatasha I use apps, but I want the web!
  • 6. @thisNatasha ServiceWorker eh? Offline Cache Worker source: Chang W. Doh
  • 7. @thisNatasha ServiceWorker eh? Offline Cache Worker Navigation Controller source: Chang W. Doh
  • 8. @thisNatasha ServiceWorker eh? Offline Cache Worker Navigation Controller Event Manager source: Chang W. Doh
  • 9. @thisNatasha Offline Cache Worker Navigation Controller Event Manager ServiceWorker eh? source: Chang W. Doh
  • 10. @thisNatasha ServiceWorker eh? source: Chang W. Doh Control request / response flow Load a cached copy of a resource
  • 11. @thisNatasha ServiceWorker eh? source: Chang W. Doh Push & Background Sync Cache Control / Custom Response Faster Load Time! Control request / response flow Load a cached copy of a resource
  • 12. @thisNatasha ServiceWorker eh? source: Chang W. Doh Control request / response flow Load a cached copy of a resource Push & Background Sync Cache Control / Custom Response Faster Load Time!
  • 13. @thisNatasha Ok fine, but what is it? Worker: script separate from the webpage
  • 14. @thisNatasha Ok fine, but what is it? Worker: script separate from the webpageDifferent Lifecycle
  • 15. @thisNatasha Ok fine, but what is it? Worker: script separate from the webpageDifferent Lifecycle Terminated when not in use
  • 16. @thisNatasha Ok fine, but what is it? Worker: script separate from the webpageDifferent Lifecycle “In terms of network control, it acts like a proxy server sitting on the client, you get to decide what to do on a request-by-request basis. You can use this to make stuff work faster, offline, or build new features.” Jake Archibald Terminated when not in use
  • 18. @thisNatasha Two APIs one interface representing a proxy for a value not necessarily known when that thing is created… (um, Promises) Fetch Gives ServiceWorkers the powers to manage network requests and return responses for resources https://fetch.spec.whatwg.org/ https://slightlyoff.github.io/ServiceWorke r/spec/service_worker/index.html#cach e-objects Cache Save fetched responses, return these responses later, not part of HTTP cache + Promises
  • 27. @thisNatasha Register Register your ServiceWorker in your main JavaScript file. // filename: app.js if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js').then(function(registration) { // Registration was successful console.log('ServiceWorker registration successful, scope: ', registration.scope); }).catch(function(err) { // registration failed console.log('ServiceWorker registration failed: ', err); }); } source: html5rocks
  • 28. @thisNatasha Register Register your ServiceWorker in your main JavaScript file. // filename: app.js if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js').then(function(registration) { // Registration was successful console.log('ServiceWorker registration successful, scope: ', registration.scope); }).catch(function(err) { // registration failed console.log('ServiceWorker registration failed: ', err); }); } source: html5rocks app.js
  • 29. @thisNatasha Register Register your ServiceWorker in your main JavaScript file. // filename: app.js if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js').then(function(registration) { // Registration was successful console.log('ServiceWorker registration successful, scope: ', registration.scope); }).catch(function(err) { // registration failed console.log('ServiceWorker registration failed: ', err); }); } source: html5rocks SW location
  • 30. @thisNatasha Register Register your ServiceWorker in your main JavaScript file. // filename: app.js if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js').then(function(registration) { // Registration was successful console.log('ServiceWorker registration successful, scope: ', registration.scope); }).catch(function(err) { // registration failed console.log('ServiceWorker registration failed: ', err); }); } source: html5rocks Browser does the rest!
  • 31. @thisNatasha Create sw.js Or whatever you want to call your ServiceWorker javascript file... // filename: sw.js TIP: sw.js goes in the root of the domain
  • 32. @thisNatasha Install Give assets you want to run offline // filename: sw.js // The files we want to cache var shellcache = 'shell-v1'; var urlsToCache = [ '/', '/app/css/dist/bootstrap.min.css', '/app/js/dist/angular.min.js', '/app/js/dist/jquery-1.11.2.min.js', '/app/js/dist/bootstrap.min.js' ]; // INSTALL self.addEventListener('install', function(event) { // Perform install steps event.waitUntil( caches.open(shellcache) //our cache! .then(function(cache) { console.log('Opened cache'); return cache.addAll(urlsToCache); //pass all our urls! }) ); });
  • 33. @thisNatasha // filename: sw.js // The files we want to cache var shellcache = 'shell-v1'; var urlsToCache = [ '/', '/app/css/dist/bootstrap.min.css', '/app/js/dist/angular.min.js', '/app/js/dist/jquery-1.11.2.min.js', '/app/js/dist/bootstrap.min.js' ]; // INSTALL self.addEventListener('install', function(event) { // Perform install steps event.waitUntil( caches.open(shellcache) //our cache! .then(function(cache) { console.log('Opened cache'); return cache.addAll(urlsToCache); //pass all our urls! }) ); }); Install Give assets you want to run offline Setup and populate caches!
  • 34. @thisNatasha // filename: sw.js // The files we want to cache var shellcache = 'shell-v1'; var urlsToCache = [ '/', '/app/css/dist/bootstrap.min.css', '/app/js/dist/angular.min.js', '/app/js/dist/jquery-1.11.2.min.js', '/app/js/dist/bootstrap.min.js' ]; // INSTALL self.addEventListener('install', function(event) { // Perform install steps event.waitUntil( caches.open(shellcache) //our cache! .then(function(cache) { console.log('Opened cache'); return cache.addAll(urlsToCache); //pass all our urls! }) ); }); Install opened cache! Give assets you want to run offline
  • 35. @thisNatasha // filename: sw.js // The files we want to cache var shellcache = 'shell-v1'; var urlsToCache = [ '/', '/app/css/dist/bootstrap.min.css', '/app/js/dist/angular.min.js', '/app/js/dist/jquery-1.11.2.min.js', '/app/js/dist/bootstrap.min.js' ]; // INSTALL self.addEventListener('install', function(event) { // Perform install steps event.waitUntil( caches.open(shellcache) //our cache! .then(function(cache) { console.log('Opened cache'); return cache.addAll(urlsToCache); //pass all our urls! }) ); }); Install pass in array of files Give assets you want to run offline
  • 36. @thisNatasha // filename: sw.js // The files we want to cache var shellcache = 'shell-v1'; var urlsToCache = [ '/', '/app/css/dist/bootstrap.min.css', '/app/js/dist/angular.min.js', '/app/js/dist/jquery-1.11.2.min.js', '/app/js/dist/bootstrap.min.js' ]; // INSTALL self.addEventListener('install', function(event) { // Perform install steps event.waitUntil( caches.open(shellcache) //our cache! .then(function(cache) { console.log('Opened cache'); return cache.addAll(urlsToCache); //pass all our urls! }) ); }); Install TIP: everything must cache at install to be successful! Give assets you want to run offline
  • 39. @thisNatasha Fetch Detect network fetches // detect fetches self.addEventListener('fetch', function(event) { event.respondWith( caches.match(event.request) .then(function(response) { … }) ); }); 1st Visit: Install ServiceWorker Later visits + navigation: worker kicks in!
  • 40. @thisNatasha Fetch // detect fetches self.addEventListener('fetch', function(event) { event.respondWith( caches.match(event.request) .then(function(response) { … }) ); }); Worker will receive “fetch” events Detect network fetches
  • 41. @thisNatasha Fetch // detect fetches self.addEventListener('fetch', function(event) { event.respondWith( caches.match(event.request) .then(function(response) { … }) ); }); Worker will receive “fetch” events fetch API allows us to respond! Detect network fetches
  • 42. @thisNatasha // detect fetches self.addEventListener('fetch', function(event) { event.respondWith( caches.match(event.request) .then(function(response) { … }) ); }); Fetch Worker will receive “fetch” events Manual response, Network fetch, or cached resouce! Detect network fetches
  • 43. @thisNatasha Fetch // detect fetches self.addEventListener('fetch', function(event) { event.respondWith( caches.match(event.request) .then(function(response) { … }) ); }); Worker will receive “fetch” events gives info about request Detect network fetches
  • 44. @thisNatasha // sw.js self.addEventListener('fetch', function(event) { event.respondWith( caches.match(event.request) .then(function(response) { if (response) { return response; // cache hit! return response } // IMPORTANT: Clone the request. 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; } // IMPORTANT: Clone the response. var responseToCache = response.clone(); caches.open(CACHE_NAME) .then(function(cache) { cache.put(event.request, responseToCache); Caching Detected fetches, return match if so or get from network as fallback pass promise caches.match
  • 45. @thisNatasha // sw.js self.addEventListener('fetch', function(event) { event.respondWith( caches.match(event.request) .then(function(response) { if (response) { return response; // cache hit! return response } // IMPORTANT: Clone the request. 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; } // IMPORTANT: Clone the response. var responseToCache = response.clone(); caches.open(CACHE_NAME) .then(function(cache) { cache.put(event.request, responseToCache); Caching hmmm, any matches in my caches? Detected fetches, return match if so or get from network as fallback
  • 46. @thisNatasha Caching // sw.js self.addEventListener('fetch', function(event) { event.respondWith( caches.match(event.request) .then(function(response) { if (response) { return response; // cache hit! return response } // IMPORTANT: Clone the request. 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; } // IMPORTANT: Clone the response. var responseToCache = response.clone(); caches.open(CACHE_NAME) .then(function(cache) { cache.put(event.request, responseToCache); Got it! Awesome, so return it! Detected fetches, return match if so or get from network as fallback
  • 47. @thisNatasha Caching // sw.js self.addEventListener('fetch', function(event) { event.respondWith( caches.match(event.request) .then(function(response) { if (response) { return response; // cache hit! return response } // IMPORTANT: Clone the request. 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; } // IMPORTANT: Clone the response. var responseToCache = response.clone(); caches.open(CACHE_NAME) .then(function(cache) { cache.put(event.request, responseToCache); Aw nothing in cache, get from network Detected fetches, return match if so or get from network as fallback
  • 48. @thisNatasha Caching Got it from the network? Why not add to the cache? // sw.js return fetch(fetchRequest).then( function(response) { // Check if we received a valid response if(!response || response.status !== 200 || response.type !== 'basic') { return response; } // IMPORTANT: Clone the response. A response is a stream // and because we want the browser to consume the response // as well as the cache consuming the response, we need // to clone it so we have 2 stream. var responseToCache = response.clone(); caches.open(CACHE_NAME) .then(function(cache) { cache.put(event.request, responseToCache); }); return response; } ); }) ); });
  • 49. @thisNatasha Caching Got it from the network? Why not add to the cache? // sw.js return fetch(fetchRequest).then( function(response) { // Check if we received a valid response if(!response || response.status !== 200 || response.type !== 'basic') { return response; } // IMPORTANT: Clone the response. A response is a stream // and because we want the browser to consume the response // as well as the cache consuming the response, we need // to clone it so we have 2 stream. var responseToCache = response.clone(); caches.open(CACHE_NAME) .then(function(cache) { cache.put(event.request, responseToCache); }); return response; } ); }) ); check response
  • 50. @thisNatasha Caching Got it from the network? Why not add to the cache? // sw.js return fetch(fetchRequest).then( function(response) { // Check if we received a valid response if(!response || response.status !== 200 || response.type !== 'basic') { return response; } // IMPORTANT: Clone the response. A response is a stream // and because we want the browser to consume the response // as well as the cache consuming the response, we need // to clone it so we have 2 stream. var responseToCache = response.clone(); caches.open(CACHE_NAME) .then(function(cache) { cache.put(event.request, responseToCache); }); return response; } ); }) ); clone response
  • 51. @thisNatasha Caching Got it from the network? Why not add to the cache? // sw.js return fetch(fetchRequest).then( function(response) { // Check if we received a valid response if(!response || response.status !== 200 || response.type !== 'basic') { return response; } // IMPORTANT: Clone the response. A response is a stream // and because we want the browser to consume the response // as well as the cache consuming the response, we need // to clone it so we have 2 stream. var responseToCache = response.clone(); caches.open(CACHE_NAME) .then(function(cache) { cache.put(event.request, responseToCache); }); return response; } ); }) ); add to cache
  • 52. @thisNatasha Update Updating your ServiceWorker // sw.js self.addEventListener('activate', function(event) { //var cacheWhitelist = ['shell-v1', 'blog-posts-cache-v1']; var cacheWhitelist = ['shell-v1']; event.waitUntil( caches.keys().then(function(cacheNames) { return Promise.all( cacheNames.map(function(cacheName) { if (cacheWhitelist.indexOf(cacheName) === -1) { console.log('deleting: ' + cacheName); return caches.delete(cacheName); } }) ); }) ); });
  • 53. @thisNatasha Update Updating your ServiceWorker // sw.js self.addEventListener('activate', function(event) { //var cacheWhitelist = ['shell-v1', 'blog-posts-cache-v1']; var cacheWhitelist = ['shell-v1']; event.waitUntil( caches.keys().then(function(cacheNames) { return Promise.all( cacheNames.map(function(cacheName) { if (cacheWhitelist.indexOf(cacheName) === -1) { console.log('deleting: ' + cacheName); return caches.delete(cacheName); } }) ); }) ); }); Edit and save me
  • 54. @thisNatasha Update Updating your ServiceWorker // sw.js self.addEventListener('activate', function(event) { //var cacheWhitelist = ['shell-v1', 'blog-posts-cache-v1']; var cacheWhitelist = ['shell-v1']; event.waitUntil( caches.keys().then(function(cacheNames) { return Promise.all( cacheNames.map(function(cacheName) { if (cacheWhitelist.indexOf(cacheName) === -1) { console.log('deleting: ' + cacheName); return caches.delete(cacheName); } }) ); }) ); }); Edit and save me TIP: completely close the application!
  • 55. @thisNatasha Update // sw.js self.addEventListener('activate', function(event) { //var cacheWhitelist = ['shell-v1', 'blog-posts-cache-v1']; var cacheWhitelist = ['shell-v1']; event.waitUntil( caches.keys().then(function(cacheNames) { return Promise.all( cacheNames.map(function(cacheName) { if (cacheWhitelist.indexOf(cacheName) === -1) { console.log('deleting: ' + cacheName); return caches.delete(cacheName); } }) ); }) ); }); Updating your ServiceWorker Open app and new SW should kick in!
  • 56. @thisNatasha Update Check caches need deleting or keeping // sw.js self.addEventListener('activate', function(event) { //var cacheWhitelist = ['shell-v1', 'blog-posts-cache-v1']; var cacheWhitelist = ['shell-v1']; event.waitUntil( caches.keys().then(function(cacheNames) { return Promise.all( cacheNames.map(function(cacheName) { if (cacheWhitelist.indexOf(cacheName) === -1) { console.log('deleting: ' + cacheName); return caches.delete(cacheName); } }) ); }) ); }); Let’s do some cache management! activate callback source: html5rocks
  • 57. @thisNatasha Update Check caches need deleting or keeping // sw.js self.addEventListener('activate', function(event) { var cacheWhitelist = ['shell-v1', 'blog-posts-cache-v1']; event.waitUntil( caches.keys().then(function(cacheNames) { return Promise.all( cacheNames.map(function(cacheName) { if (cacheWhitelist.indexOf(cacheName) === -1) { console.log('deleting: ' + cacheName); return caches.delete(cacheName); } }) ); }) ); }); Let’s do some cache management! defined in install step source: html5rocks
  • 58. @thisNatasha Update Check caches need deleting or keeping // sw.js self.addEventListener('activate', function(event) { var cacheWhitelist = ['shell-v1', 'blog-posts-cache-v1']; event.waitUntil( caches.keys().then(function(cacheNames) { return Promise.all( cacheNames.map(function(cacheName) { if (cacheWhitelist.indexOf(cacheName) === -1) { console.log('deleting: ' + cacheName); return caches.delete(cacheName); } }) ); }) ); }); Let’s do some cache management! loop through and delete! source: html5rocks
  • 59. @thisNatasha Cool Other Stuff! What more can I do? Push / Background Sync Mess around with fallbacks Pass in weird and wonderful responses!
  • 60. @thisNatasha Ok I see how this works, anything else I should know? TIP: Github pages are served over HTTPS
  • 61. @thisNatasha [1] ServiceWorkers mandate HTTPS TIP: Github pages are served over HTTPS
  • 62. @thisNatasha [2] So, can we use ServiceWorkers today?
  • 69. @thisNatasha New Questions Super new! What else do we need to know!? How does this scale? Does SW improve performance? How complex does development become?
  • 70. @thisNatasha Some things we couldn’t cover... [1] Extensible Web Manifesto [2] Impacted APIs
  • 72. @thisNatasha ありがとう! Natasha Rooney @thisNatasha GSMA Web Technologist W3C WebMob Co-Chair www.w3.org/Mobile/IG/ Thanks to: Matt Gaunt & Jake Archibald for their previous written work on ServiceWorker!