SlideShare ist ein Scribd-Unternehmen logo
1 von 64
Service Workers
The Practical Bits
@patmeenan
Patrick Meenan
Slides
Slideshare: http://www.slideshare.net/patrickmeenan
Twitter: @patmeenan (and to #velocityconf)
Velocity Site, attached to session information
Video: https://www.youtube.com/user/patmeenan
Office Hours: Friday, May 29 from 12:30pm-1:00pm
@patmeenan
Chrome Team @Google (performance)
WebPageTest
pmeenan@webpagetest.org
@patmeenan
The Real Experts
Alex Russell
@slightlylate
Jake Archibald
@jaffathecake
Service Workers
DOM
Resource Fetching in Chrome
DOM
Resource Fetching in Chrome
In-memory
Resource
Cache
DOM
Resource Fetching in Chrome
In-memory
Resource
Cache
Resource
Fetcher
DOM
Resource Fetching in Chrome
Resource
Fetcher
Net Stack
DOM
Resource Fetching in Chrome
In-memory
Resource
Cache
Resource
Fetcher
Net Stack
Disk
Cache
DOM
Resource Fetching in Chrome
In-memory
Resource
Cache
Resource
Fetcher
Net Stack Net
Disk
Cache
DOM
Resource Fetching in Chrome
In-memory
Resource
Cache
Resource
Fetcher
Net Stack Net
Disk
Cache
Service
Worker
SW Added and
Removed Here!
Capabilities
Sees every request for your document
- Including cross-origin
- And headers
Can synthesize responses
Supports fetch
Has a programmable cache and Indexed DB
Limitations
HTTPS documents only
Not active for first view
iFrames are separate documents
Non-CORS Cross-origin responses are opaque
No global state
- or concept of a “page”
No Sync API’s (localstorage, XHR, etc)
http://memegenerator.net/instance/62336209
Registering
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/my-app/sw.js', {
scope: '/my-app/'
});
}
https://github.com/slightlyoff/ServiceWorker/blob/master/explainer.md
Registering
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/my-app/sw.js', {
scope: '/my-app/'
});
}
https://github.com/slightlyoff/ServiceWorker/blob/master/explainer.md
Registering
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/my-app/sw.js', {
scope: '/my-app/'
});
}
https://github.com/slightlyoff/ServiceWorker/blob/master/explainer.md
Registering
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/my-app/sw.js', {
scope: '/my-app/'
});
}
https://github.com/slightlyoff/ServiceWorker/blob/master/explainer.md
Install / activate
self.addEventListener('install', function(event) {
event.waitUntil(
fetchStuffAndInitDatabases()
);
});
self.addEventListener('activate', function(event) {
// You're good to go!
});
https://github.com/slightlyoff/ServiceWorker/blob/master/explainer.md
Network Intercepting
self.addEventListener('fetch', function(event) {
event.respondWith(new Response("Hello world!"));
});
https://github.com/slightlyoff/ServiceWorker/blob/master/explainer.md
Enough Theory – Let’s Use It
Offline Content
 Most benefit for Single-Page Apps where app/data are separated
 Service Workers become progressive enhancement for offline support
Offline Content
 Pre-cache offline content
 Pass live requests through when online
- Caching the responses
 Serve cached responses when offline (if available)
 Serve offline-specific versions otherwise
Offline Content – Pre-caching
self.addEventListener( ‘install’, function(event) {
event.waitUntil(
caches.open(‘my-offline-cache-v1’).then( function(cache) {
return cache.addAll([
‘/site.js’,
‘/images/offline.png’,
‘/offline.html’]);
}));});
Offline Content – Pre-caching
self.addEventListener( ‘install’, function(event) {
event.waitUntil(
caches.open(‘my-offline-cache-v1’).then( function(cache) {
return cache.addAll([
‘/site.js’,
‘/images/offline.png’,
‘/offline.html’]);
}));});
Offline Content – Pre-caching
self.addEventListener( ‘install’, function(event) {
event.waitUntil(
caches.open(‘my-offline-cache-v1’).then( function(cache) {
return cache.addAll([
‘/site.js’,
‘/images/offline.png’,
‘/offline.html’]);
}));});
Offline Content – Pre-caching
self.addEventListener( ‘install’, function(event) {
event.waitUntil(
caches.open(‘my-offline-cache-v1’).then( function(cache) {
return cache.addAll([
‘/site.js’,
‘/images/offline.png’,
‘/offline.html’]);
}));});
Offline Content – Pre-caching
self.addEventListener( ‘install’, function(event) {
event.waitUntil(
caches.open(‘my-offline-cache-v1’).then( function(cache) {
return cache.addAll([
‘/site.js’,
‘/images/offline.png’,
‘/offline.html’]);
}));});
Offline Content – Fetch Processing
self.addEventListener( 'fetch', function(event) {
if (navigator.online) {
event.respondWith( onlineRequest(event.request) );
} else {
event.respondWith( offlineRequest(event.request) );
}
});
Offline Content – Fetch Processing
self.addEventListener( 'fetch', function(event) {
if (navigator.online) {
event.respondWith( onlineRequest(event.request) );
} else {
event.respondWith( offlineRequest(event.request) );
}
});
Offline Content – Fetch Processing
self.addEventListener( 'fetch', function(event) {
if (navigator.online) {
event.respondWith( onlineRequest(event.request) );
} else {
event.respondWith( offlineRequest(event.request) );
}
});
Offline Content – Fetch Processing
self.addEventListener( 'fetch', function(event) {
if (navigator.online) {
event.respondWith( onlineRequest(event.request) );
} else {
event.respondWith( offlineRequest(event.request) );
}
});
Offline Content – Fetch Processing
self.addEventListener( 'fetch', function(event) {
if (navigator.online) {
event.respondWith( onlineRequest(event.request) );
} else {
event.respondWith( offlineRequest(event.request) );
}
});
Offline Content – Online Response
function onlineRequest(request) {
return caches.match(request)
.then(function(response) {
…
}
);
}
Offline Content – Online Response
function onlineRequest(request) {
return caches.match(request).then(function(response) {
if (response) {
return response;
} else {
return fetch(request);
}
});
}
Offline Content – Online Response
function onlineRequest(request) {
return caches.match(request).then(function(response) {
if (response) {
return response;
} else {
return fetch(request);
}
});
}
Offline Content – Online Response
…
var fetchRequest = request.clone();
return fetch(fetchRequest).then( function(response) {
var responseToCache = response.clone();
caches.open(CACHE_NAME).then( function(cache) {
cache.put(request, responseToCache);
});
return response;
});
Offline Content – Online Response
…
var fetchRequest = request.clone();
return fetch(fetchRequest).then( function(response) {
var responseToCache = response.clone();
caches.open(CACHE_NAME).then( function(cache) {
cache.put(request, responseToCache);
});
return response;
});
Offline Content – Online Response
…
var fetchRequest = request.clone();
return fetch(fetchRequest).then( function(response) {
var responseToCache = response.clone();
caches.open(CACHE_NAME).then( function(cache) {
cache.put(request, responseToCache);
});
return response;
});
Offline Content – Online Response
…
var fetchRequest = request.clone();
return fetch(fetchRequest).then( function(response) {
var responseToCache = response.clone();
caches.open(CACHE_NAME).then( function(cache) {
cache.put(request, responseToCache);
});
return response;
});
Offline Content – Online Response
…
var fetchRequest = request.clone();
return fetch(fetchRequest).then( function(response) {
var responseToCache = response.clone();
caches.open(CACHE_NAME).then( function(cache) {
cache.put(request, responseToCache);
});
return response;
});
Offline Content – Online Response
…
var fetchRequest = request.clone();
return fetch(fetchRequest).then( function(response) {
var responseToCache = response.clone();
caches.open(CACHE_NAME).then( function(cache) {
cache.put(request, responseToCache);
});
return response;
});
Offline Content – Offline Response
function offlineRequest(request) {
if (request.url.match(/.png$/)) {
return caches.match(‘/images/offline.png’);
} else if (request.url.match(/.html$/)) {
return caches.match(‘/offline.html’);
}
…
}
Offline Content – Offline Response
function offlineRequest(request) {
if (request.url.match(/.png$/)) {
return caches.match(‘/images/offline.png’);
} else if (request.url.match(/.html$/)) {
return caches.match(‘/offline.html’);
}
…
}
Other Uses
Not limited to applications designed for offline/SPA
Legacy apps + fetch intercept = Awesome possibilities
Custom Error Pages
Fetch Request Normally
For non-200 responses serve a local error page
Not just server errors:
- DNS failures
- CDN/Proxy Errors
- Intermediaries
SPOF Prevention
Identify requests of interest
- 3rd
-party javascript
- Fonts
Set a timer
Pass fetch requests through
If timer expires before fetch completes generate error response
CDN/Origin Failover
Identify CDN requests by URL
Set a timer
Pass fetch request through
If timer expires, create fetch request to origin
Respond with first fetch request to complete
Multi-Origin/CDN
Identify CDN requests by URL
Replace CDN domain with alternate CDN (or origin)
Keep track of performance by origin
Prefer faster origin (keep measuring)
Could also race the CDNs in parallel
- Be careful about increased data
Stale-While-Revalidate
Respond with local cached resource
- Ignoring Expires, max-age, etc.
Pass fetch request through in parallel
Update cache with new response
Works best for known resources (analytics/ads JS, etc)
Prefetch
Custom response headers with prefetch resources
When idle, prefetch suggested resources
Resource Prioritization/Scheduling
Track in-flight requests
Make scheduling decisions as new requests come in
Custom application-aware scheduling logic
- Delay JS if it is known to be at the end
- Delay footer images
- etc
Delta Compression
Delta compression for build->build updates
- Include version in URL scheme
- Get latest version number from cache
- Request delta from server
- Apply patch
- Cache new version
New compression algorithms
Custom Compression
New compression algorithms
- Brotli
- Fractal image compression
- JSON-specific dictionaries
- Application-specific
Prove-out new algorithms before standardizing
…as long as it can be implemented in JS and code size is
reasonable
Incremental Progressive Images
Identify JPEG image requests from known origin
Synthesize response
Range request (or smarter) for first few scans
Stream initial range into synthesized response
Range request for remaining image (some point later)
Append remaining data into synthesized response
Drawing Images Locally
 930 x 11,362 px WebPageTest waterfall
 351KB compressed PNG
 42 MB in-memory (server) to generate
 < 20KB compressed JSON data to describe
 Prefer actual images for WPT waterfalls for easier embedding
- Otherwise SVG, Canvas or DOM would work
Drawing Images Locally*
Identify appropriate requests (i.e. waterfall.png?...)
Fetch data necessary to draw image
Draw to canvas
Extract as PNG
Synthesize PNG response
* Work in progress, coming soon
Metrics/Debugging
Pass all requests through
Passively observe timings and success
Report metrics back
Gives visibility into failures and requests that are in flight
- Unlike resource timing
And there’s more…
Required for…
Push Notifications
- https://gauntface.com/blog/2014/12/15/push-notifications-service-worker
Background Sync
- https://github.com/slightlyoff/BackgroundSync/blob/master/explainer.md
GeoFencing
- https://github.com/slightlyoff/Geofencing
Availability
Chrome Stable (40+)
Opera (27+)
Firefox (Nightly)
Composable
Service workers can “importScripts”
Begging for a framework to handle pluggable pipeline
- With compatible plugins for processing
- Delta compression + scheduling + Stale While Revalidate…
- Just a matter of importing the libs
Thank You!
@patmeenan
pmeenan@webpagetest.org

Weitere ähnliche Inhalte

Was ist angesagt?

Performance Metrics in a Day with Selenium
Performance Metrics in a Day with SeleniumPerformance Metrics in a Day with Selenium
Performance Metrics in a Day with Selenium
Mark Watson
 
Automated Web App Performance Testing Using WebDriver
Automated Web App Performance Testing Using WebDriverAutomated Web App Performance Testing Using WebDriver
Automated Web App Performance Testing Using WebDriver
seleniumconf
 
Measuring the visual experience of website performance
Measuring the visual experience of website performanceMeasuring the visual experience of website performance
Measuring the visual experience of website performance
Patrick Meenan
 

Was ist angesagt? (20)

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
 
Service Worker - Reliability bits
Service Worker - Reliability bitsService Worker - Reliability bits
Service Worker - Reliability bits
 
PWA 與 Service Worker
PWA 與 Service WorkerPWA 與 Service Worker
PWA 與 Service Worker
 
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
 
Using Modern Browser APIs to Improve the Performance of Your Web Applications
Using Modern Browser APIs to Improve the Performance of Your Web ApplicationsUsing Modern Browser APIs to Improve the Performance of Your Web Applications
Using Modern Browser APIs to Improve the Performance of Your Web Applications
 
Performance Metrics in a Day with Selenium
Performance Metrics in a Day with SeleniumPerformance Metrics in a Day with Selenium
Performance Metrics in a Day with Selenium
 
Making the web faster
Making the web fasterMaking the web faster
Making the web faster
 
Service worker API
Service worker APIService worker API
Service worker API
 
Forensic Tools for In-Depth Performance Investigations
Forensic Tools for In-Depth Performance InvestigationsForensic Tools for In-Depth Performance Investigations
Forensic Tools for In-Depth Performance Investigations
 
A web perf dashboard up & running in 90 minutes presentation
A web perf dashboard up & running in 90 minutes presentationA web perf dashboard up & running in 90 minutes presentation
A web perf dashboard up & running in 90 minutes presentation
 
Search 500-video-clips
Search 500-video-clipsSearch 500-video-clips
Search 500-video-clips
 
Automated Web App Performance Testing Using WebDriver
Automated Web App Performance Testing Using WebDriverAutomated Web App Performance Testing Using WebDriver
Automated Web App Performance Testing Using WebDriver
 
Metrics, metrics everywhere (but where the heck do you start?)
Metrics, metrics everywhere (but where the heck do you start?)Metrics, metrics everywhere (but where the heck do you start?)
Metrics, metrics everywhere (but where the heck do you start?)
 
Measuring Continuity
Measuring ContinuityMeasuring Continuity
Measuring Continuity
 
Choosing a Javascript Framework
Choosing a Javascript FrameworkChoosing a Javascript Framework
Choosing a Javascript Framework
 
High Performance JavaScript - jQuery Conference SF Bay Area 2010
High Performance JavaScript - jQuery Conference SF Bay Area 2010High Performance JavaScript - jQuery Conference SF Bay Area 2010
High Performance JavaScript - jQuery Conference SF Bay Area 2010
 
Measuring the visual experience of website performance
Measuring the visual experience of website performanceMeasuring the visual experience of website performance
Measuring the visual experience of website performance
 
Enough with the JavaScript already!
Enough with the JavaScript already!Enough with the JavaScript already!
Enough with the JavaScript already!
 
PowerShell: Through the SharePoint Looking Glass
PowerShell: Through the SharePoint Looking GlassPowerShell: Through the SharePoint Looking Glass
PowerShell: Through the SharePoint Looking Glass
 
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
 

Andere mochten auch

Andere mochten auch (20)

Scaling Front-End Performance - Velocity 2016
Scaling Front-End Performance - Velocity 2016Scaling Front-End Performance - Velocity 2016
Scaling Front-End Performance - Velocity 2016
 
What You Need to Know About Email Authentication
What You Need to Know About Email AuthenticationWhat You Need to Know About Email Authentication
What You Need to Know About Email Authentication
 
Machine Learning RUM - Velocity 2016
Machine Learning RUM - Velocity 2016Machine Learning RUM - Velocity 2016
Machine Learning RUM - Velocity 2016
 
TLS - 2016 Velocity Training
TLS - 2016 Velocity TrainingTLS - 2016 Velocity Training
TLS - 2016 Velocity Training
 
Service workers your applications never felt so good
Service workers   your applications never felt so goodService workers   your applications never felt so good
Service workers your applications never felt so good
 
Introduction to Progressive Web Apps, Google Developer Summit, Seoul - South ...
Introduction to Progressive Web Apps, Google Developer Summit, Seoul - South ...Introduction to Progressive Web Apps, Google Developer Summit, Seoul - South ...
Introduction to Progressive Web Apps, Google Developer Summit, Seoul - South ...
 
Velocity 2015 linux perf tools
Velocity 2015 linux perf toolsVelocity 2015 linux perf tools
Velocity 2015 linux perf tools
 
Selecting and deploying automated optimization solutions
Selecting and deploying automated optimization solutionsSelecting and deploying automated optimization solutions
Selecting and deploying automated optimization solutions
 
Service Worker 101 (한국어)
Service Worker 101 (한국어)Service Worker 101 (한국어)
Service Worker 101 (한국어)
 
WebPagetest Power Users - Velocity 2014
WebPagetest Power Users - Velocity 2014WebPagetest Power Users - Velocity 2014
WebPagetest Power Users - Velocity 2014
 
Service workers in JavaScript
Service workers in JavaScriptService workers in JavaScript
Service workers in JavaScript
 
Disrupting the application eco system with progressive web applications
Disrupting the application eco system with progressive web applicationsDisrupting the application eco system with progressive web applications
Disrupting the application eco system with progressive web applications
 
"Service Worker: Let Your Web App Feel Like a Native "
"Service Worker: Let Your Web App Feel Like a Native ""Service Worker: Let Your Web App Feel Like a Native "
"Service Worker: Let Your Web App Feel Like a Native "
 
Service workers - Velocity 2016 Training
Service workers - Velocity 2016 TrainingService workers - Velocity 2016 Training
Service workers - Velocity 2016 Training
 
Fail Well
Fail WellFail Well
Fail Well
 
Scalable Angular 2 Application Architecture
Scalable Angular 2 Application ArchitectureScalable Angular 2 Application Architecture
Scalable Angular 2 Application Architecture
 
Service Worker 201 (한국어)
Service Worker 201 (한국어)Service Worker 201 (한국어)
Service Worker 201 (한국어)
 
Measuring performance - Velocity 2016 Training
Measuring performance - Velocity 2016 TrainingMeasuring performance - Velocity 2016 Training
Measuring performance - Velocity 2016 Training
 
Progressive Web Applications
Progressive Web ApplicationsProgressive Web Applications
Progressive Web Applications
 
Progressive Web Apps [pt_BR]
Progressive Web Apps [pt_BR]Progressive Web Apps [pt_BR]
Progressive Web Apps [pt_BR]
 

Ähnlich wie Service Workers for Performance

Build web application by express
Build web application by expressBuild web application by express
Build web application by express
Shawn Meng
 
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
 
BlackBerry DevCon 2011 - PhoneGap and WebWorks
BlackBerry DevCon 2011 - PhoneGap and WebWorksBlackBerry DevCon 2011 - PhoneGap and WebWorks
BlackBerry DevCon 2011 - PhoneGap and WebWorks
mwbrooks
 
Do you want a SDK with that API? (Nordic APIS April 2014)
Do you want a SDK with that API? (Nordic APIS April 2014)Do you want a SDK with that API? (Nordic APIS April 2014)
Do you want a SDK with that API? (Nordic APIS April 2014)
Nordic APIs
 

Ähnlich wie Service Workers for Performance (20)

Express Presentation
Express PresentationExpress Presentation
Express Presentation
 
Cross Domain Web
Mashups with JQuery and Google App Engine
Cross Domain Web
Mashups with JQuery and Google App EngineCross Domain Web
Mashups with JQuery and Google App Engine
Cross Domain Web
Mashups with JQuery and Google App Engine
 
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
 
Building Scalable Websites with Perl
Building Scalable Websites with PerlBuilding Scalable Websites with Perl
Building Scalable Websites with Perl
 
Build web application by express
Build web application by expressBuild web application by express
Build web application by express
 
Building with Firebase
Building with FirebaseBuilding with Firebase
Building with Firebase
 
huhu
huhuhuhu
huhu
 
JQuery UK Service Workers Talk
JQuery UK Service Workers TalkJQuery UK Service Workers Talk
JQuery UK Service Workers Talk
 
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?
 
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
 
BlackBerry DevCon 2011 - PhoneGap and WebWorks
BlackBerry DevCon 2011 - PhoneGap and WebWorksBlackBerry DevCon 2011 - PhoneGap and WebWorks
BlackBerry DevCon 2011 - PhoneGap and WebWorks
 
Caching Up and Down the Stack
Caching Up and Down the StackCaching Up and Down the Stack
Caching Up and Down the Stack
 
Offline Capabilities of MindMeister
Offline Capabilities of MindMeisterOffline Capabilities of MindMeister
Offline Capabilities of MindMeister
 
State of the resource timing api
State of the resource timing apiState of the resource timing api
State of the resource timing api
 
Frontend Servers and NGINX: What, Where and How
Frontend Servers and NGINX: What, Where and HowFrontend Servers and NGINX: What, Where and How
Frontend Servers and NGINX: What, Where and How
 
20160905 - BrisJS - nightwatch testing
20160905 - BrisJS - nightwatch testing20160905 - BrisJS - nightwatch testing
20160905 - BrisJS - nightwatch testing
 
The Big Picture and How to Get Started
The Big Picture and How to Get StartedThe Big Picture and How to Get Started
The Big Picture and How to Get Started
 
Do you want a SDK with that API? (Nordic APIS April 2014)
Do you want a SDK with that API? (Nordic APIS April 2014)Do you want a SDK with that API? (Nordic APIS April 2014)
Do you want a SDK with that API? (Nordic APIS April 2014)
 
Make the Web 3D
Make the Web 3DMake the Web 3D
Make the Web 3D
 
Quick Fetch API Introduction
Quick Fetch API IntroductionQuick Fetch API Introduction
Quick Fetch API Introduction
 

Mehr von Patrick Meenan

Hands on performance testing and analysis with web pagetest
Hands on performance testing and analysis with web pagetestHands on performance testing and analysis with web pagetest
Hands on performance testing and analysis with web pagetest
Patrick Meenan
 

Mehr von Patrick Meenan (15)

Resource Prioritization
Resource PrioritizationResource Prioritization
Resource Prioritization
 
HTTP/2 Prioritization
HTTP/2 PrioritizationHTTP/2 Prioritization
HTTP/2 Prioritization
 
Getting the most out of WebPageTest
Getting the most out of WebPageTestGetting the most out of WebPageTest
Getting the most out of WebPageTest
 
Http2 in practice
Http2 in practiceHttp2 in practice
Http2 in practice
 
Resource loading, prioritization, HTTP/2 - oh my!
Resource loading, prioritization, HTTP/2 - oh my!Resource loading, prioritization, HTTP/2 - oh my!
Resource loading, prioritization, HTTP/2 - oh my!
 
How fast is it?
How fast is it?How fast is it?
How fast is it?
 
Mobile web performance - MoDev East
Mobile web performance - MoDev EastMobile web performance - MoDev East
Mobile web performance - MoDev East
 
Tracking Performance - Velocity NYC 2013
Tracking Performance - Velocity NYC 2013Tracking Performance - Velocity NYC 2013
Tracking Performance - Velocity NYC 2013
 
Image optimization
Image optimizationImage optimization
Image optimization
 
Google I/O 2012 - Protecting your user experience while integrating 3rd party...
Google I/O 2012 - Protecting your user experience while integrating 3rd party...Google I/O 2012 - Protecting your user experience while integrating 3rd party...
Google I/O 2012 - Protecting your user experience while integrating 3rd party...
 
Velocity 2012 - Taming the Mobile Beast
Velocity 2012 - Taming the Mobile BeastVelocity 2012 - Taming the Mobile Beast
Velocity 2012 - Taming the Mobile Beast
 
Frontend SPOF
Frontend SPOFFrontend SPOF
Frontend SPOF
 
Web Performance Optimization
Web Performance OptimizationWeb Performance Optimization
Web Performance Optimization
 
Web performance testing
Web performance testingWeb performance testing
Web performance testing
 
Hands on performance testing and analysis with web pagetest
Hands on performance testing and analysis with web pagetestHands on performance testing and analysis with web pagetest
Hands on performance testing and analysis with web pagetest
 

Kürzlich hochgeladen

+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@
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 

Kürzlich hochgeladen (20)

What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
+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...
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
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
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
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...
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
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...
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 

Service Workers for Performance

  • 1. Service Workers The Practical Bits @patmeenan Patrick Meenan
  • 2. Slides Slideshare: http://www.slideshare.net/patrickmeenan Twitter: @patmeenan (and to #velocityconf) Velocity Site, attached to session information Video: https://www.youtube.com/user/patmeenan Office Hours: Friday, May 29 from 12:30pm-1:00pm @patmeenan
  • 3. Chrome Team @Google (performance) WebPageTest pmeenan@webpagetest.org @patmeenan
  • 4. The Real Experts Alex Russell @slightlylate Jake Archibald @jaffathecake
  • 7. DOM Resource Fetching in Chrome In-memory Resource Cache
  • 8. DOM Resource Fetching in Chrome In-memory Resource Cache Resource Fetcher
  • 9. DOM Resource Fetching in Chrome Resource Fetcher Net Stack
  • 10. DOM Resource Fetching in Chrome In-memory Resource Cache Resource Fetcher Net Stack Disk Cache
  • 11. DOM Resource Fetching in Chrome In-memory Resource Cache Resource Fetcher Net Stack Net Disk Cache
  • 12. DOM Resource Fetching in Chrome In-memory Resource Cache Resource Fetcher Net Stack Net Disk Cache Service Worker SW Added and Removed Here!
  • 13. Capabilities Sees every request for your document - Including cross-origin - And headers Can synthesize responses Supports fetch Has a programmable cache and Indexed DB
  • 14. Limitations HTTPS documents only Not active for first view iFrames are separate documents Non-CORS Cross-origin responses are opaque No global state - or concept of a “page” No Sync API’s (localstorage, XHR, etc)
  • 16. Registering if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/my-app/sw.js', { scope: '/my-app/' }); } https://github.com/slightlyoff/ServiceWorker/blob/master/explainer.md
  • 17. Registering if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/my-app/sw.js', { scope: '/my-app/' }); } https://github.com/slightlyoff/ServiceWorker/blob/master/explainer.md
  • 18. Registering if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/my-app/sw.js', { scope: '/my-app/' }); } https://github.com/slightlyoff/ServiceWorker/blob/master/explainer.md
  • 19. Registering if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/my-app/sw.js', { scope: '/my-app/' }); } https://github.com/slightlyoff/ServiceWorker/blob/master/explainer.md
  • 20. Install / activate self.addEventListener('install', function(event) { event.waitUntil( fetchStuffAndInitDatabases() ); }); self.addEventListener('activate', function(event) { // You're good to go! }); https://github.com/slightlyoff/ServiceWorker/blob/master/explainer.md
  • 21. Network Intercepting self.addEventListener('fetch', function(event) { event.respondWith(new Response("Hello world!")); }); https://github.com/slightlyoff/ServiceWorker/blob/master/explainer.md
  • 22. Enough Theory – Let’s Use It
  • 23. Offline Content  Most benefit for Single-Page Apps where app/data are separated  Service Workers become progressive enhancement for offline support
  • 24. Offline Content  Pre-cache offline content  Pass live requests through when online - Caching the responses  Serve cached responses when offline (if available)  Serve offline-specific versions otherwise
  • 25. Offline Content – Pre-caching self.addEventListener( ‘install’, function(event) { event.waitUntil( caches.open(‘my-offline-cache-v1’).then( function(cache) { return cache.addAll([ ‘/site.js’, ‘/images/offline.png’, ‘/offline.html’]); }));});
  • 26. Offline Content – Pre-caching self.addEventListener( ‘install’, function(event) { event.waitUntil( caches.open(‘my-offline-cache-v1’).then( function(cache) { return cache.addAll([ ‘/site.js’, ‘/images/offline.png’, ‘/offline.html’]); }));});
  • 27. Offline Content – Pre-caching self.addEventListener( ‘install’, function(event) { event.waitUntil( caches.open(‘my-offline-cache-v1’).then( function(cache) { return cache.addAll([ ‘/site.js’, ‘/images/offline.png’, ‘/offline.html’]); }));});
  • 28. Offline Content – Pre-caching self.addEventListener( ‘install’, function(event) { event.waitUntil( caches.open(‘my-offline-cache-v1’).then( function(cache) { return cache.addAll([ ‘/site.js’, ‘/images/offline.png’, ‘/offline.html’]); }));});
  • 29. Offline Content – Pre-caching self.addEventListener( ‘install’, function(event) { event.waitUntil( caches.open(‘my-offline-cache-v1’).then( function(cache) { return cache.addAll([ ‘/site.js’, ‘/images/offline.png’, ‘/offline.html’]); }));});
  • 30. Offline Content – Fetch Processing self.addEventListener( 'fetch', function(event) { if (navigator.online) { event.respondWith( onlineRequest(event.request) ); } else { event.respondWith( offlineRequest(event.request) ); } });
  • 31. Offline Content – Fetch Processing self.addEventListener( 'fetch', function(event) { if (navigator.online) { event.respondWith( onlineRequest(event.request) ); } else { event.respondWith( offlineRequest(event.request) ); } });
  • 32. Offline Content – Fetch Processing self.addEventListener( 'fetch', function(event) { if (navigator.online) { event.respondWith( onlineRequest(event.request) ); } else { event.respondWith( offlineRequest(event.request) ); } });
  • 33. Offline Content – Fetch Processing self.addEventListener( 'fetch', function(event) { if (navigator.online) { event.respondWith( onlineRequest(event.request) ); } else { event.respondWith( offlineRequest(event.request) ); } });
  • 34. Offline Content – Fetch Processing self.addEventListener( 'fetch', function(event) { if (navigator.online) { event.respondWith( onlineRequest(event.request) ); } else { event.respondWith( offlineRequest(event.request) ); } });
  • 35. Offline Content – Online Response function onlineRequest(request) { return caches.match(request) .then(function(response) { … } ); }
  • 36. Offline Content – Online Response function onlineRequest(request) { return caches.match(request).then(function(response) { if (response) { return response; } else { return fetch(request); } }); }
  • 37. Offline Content – Online Response function onlineRequest(request) { return caches.match(request).then(function(response) { if (response) { return response; } else { return fetch(request); } }); }
  • 38. Offline Content – Online Response … var fetchRequest = request.clone(); return fetch(fetchRequest).then( function(response) { var responseToCache = response.clone(); caches.open(CACHE_NAME).then( function(cache) { cache.put(request, responseToCache); }); return response; });
  • 39. Offline Content – Online Response … var fetchRequest = request.clone(); return fetch(fetchRequest).then( function(response) { var responseToCache = response.clone(); caches.open(CACHE_NAME).then( function(cache) { cache.put(request, responseToCache); }); return response; });
  • 40. Offline Content – Online Response … var fetchRequest = request.clone(); return fetch(fetchRequest).then( function(response) { var responseToCache = response.clone(); caches.open(CACHE_NAME).then( function(cache) { cache.put(request, responseToCache); }); return response; });
  • 41. Offline Content – Online Response … var fetchRequest = request.clone(); return fetch(fetchRequest).then( function(response) { var responseToCache = response.clone(); caches.open(CACHE_NAME).then( function(cache) { cache.put(request, responseToCache); }); return response; });
  • 42. Offline Content – Online Response … var fetchRequest = request.clone(); return fetch(fetchRequest).then( function(response) { var responseToCache = response.clone(); caches.open(CACHE_NAME).then( function(cache) { cache.put(request, responseToCache); }); return response; });
  • 43. Offline Content – Online Response … var fetchRequest = request.clone(); return fetch(fetchRequest).then( function(response) { var responseToCache = response.clone(); caches.open(CACHE_NAME).then( function(cache) { cache.put(request, responseToCache); }); return response; });
  • 44. Offline Content – Offline Response function offlineRequest(request) { if (request.url.match(/.png$/)) { return caches.match(‘/images/offline.png’); } else if (request.url.match(/.html$/)) { return caches.match(‘/offline.html’); } … }
  • 45. Offline Content – Offline Response function offlineRequest(request) { if (request.url.match(/.png$/)) { return caches.match(‘/images/offline.png’); } else if (request.url.match(/.html$/)) { return caches.match(‘/offline.html’); } … }
  • 46. Other Uses Not limited to applications designed for offline/SPA Legacy apps + fetch intercept = Awesome possibilities
  • 47. Custom Error Pages Fetch Request Normally For non-200 responses serve a local error page Not just server errors: - DNS failures - CDN/Proxy Errors - Intermediaries
  • 48. SPOF Prevention Identify requests of interest - 3rd -party javascript - Fonts Set a timer Pass fetch requests through If timer expires before fetch completes generate error response
  • 49. CDN/Origin Failover Identify CDN requests by URL Set a timer Pass fetch request through If timer expires, create fetch request to origin Respond with first fetch request to complete
  • 50. Multi-Origin/CDN Identify CDN requests by URL Replace CDN domain with alternate CDN (or origin) Keep track of performance by origin Prefer faster origin (keep measuring) Could also race the CDNs in parallel - Be careful about increased data
  • 51. Stale-While-Revalidate Respond with local cached resource - Ignoring Expires, max-age, etc. Pass fetch request through in parallel Update cache with new response Works best for known resources (analytics/ads JS, etc)
  • 52. Prefetch Custom response headers with prefetch resources When idle, prefetch suggested resources
  • 53. Resource Prioritization/Scheduling Track in-flight requests Make scheduling decisions as new requests come in Custom application-aware scheduling logic - Delay JS if it is known to be at the end - Delay footer images - etc
  • 54. Delta Compression Delta compression for build->build updates - Include version in URL scheme - Get latest version number from cache - Request delta from server - Apply patch - Cache new version New compression algorithms
  • 55. Custom Compression New compression algorithms - Brotli - Fractal image compression - JSON-specific dictionaries - Application-specific Prove-out new algorithms before standardizing …as long as it can be implemented in JS and code size is reasonable
  • 56. Incremental Progressive Images Identify JPEG image requests from known origin Synthesize response Range request (or smarter) for first few scans Stream initial range into synthesized response Range request for remaining image (some point later) Append remaining data into synthesized response
  • 57. Drawing Images Locally  930 x 11,362 px WebPageTest waterfall  351KB compressed PNG  42 MB in-memory (server) to generate  < 20KB compressed JSON data to describe  Prefer actual images for WPT waterfalls for easier embedding - Otherwise SVG, Canvas or DOM would work
  • 58. Drawing Images Locally* Identify appropriate requests (i.e. waterfall.png?...) Fetch data necessary to draw image Draw to canvas Extract as PNG Synthesize PNG response * Work in progress, coming soon
  • 59. Metrics/Debugging Pass all requests through Passively observe timings and success Report metrics back Gives visibility into failures and requests that are in flight - Unlike resource timing
  • 61. Required for… Push Notifications - https://gauntface.com/blog/2014/12/15/push-notifications-service-worker Background Sync - https://github.com/slightlyoff/BackgroundSync/blob/master/explainer.md GeoFencing - https://github.com/slightlyoff/Geofencing
  • 62. Availability Chrome Stable (40+) Opera (27+) Firefox (Nightly)
  • 63. Composable Service workers can “importScripts” Begging for a framework to handle pluggable pipeline - With compatible plugins for processing - Delta compression + scheduling + Stale While Revalidate… - Just a matter of importing the libs