Your SlideShare is downloading. ×
0
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Service Workers for Performance
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Service Workers for Performance

659

Published on

Service Workers presentation from the 2015 Velocity Conference

Service Workers presentation from the 2015 Velocity Conference

Published in: Technology
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
659
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
5
Comments
0
Likes
4
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 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
  • 5. Service Workers
  • 6. DOM Resource Fetching in Chrome
  • 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)
  • 15. http://memegenerator.net/instance/62336209
  • 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
  • 60. And there’s more…
  • 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
  • 64. Thank You! @patmeenan pmeenan@webpagetest.org

×