CARVIEW |
Select Language
HTTP/2 200
date: Sat, 26 Jul 2025 06:06:36 GMT
content-type: text/html; charset=utf-8
cache-control: max-age=0, private, must-revalidate
cf-cache-status: DYNAMIC
link: ; rel=preload; as=style; nopush,; rel=preload; as=script; nopush,; rel=preload; as=style; nopush,; rel=preload; as=script; nopush,; rel=preload; as=script; nopush
nel: {"report_to":"heroku-nel","response_headers":["Via"],"max_age":3600,"success_fraction":0.01,"failure_fraction":0.1}
referrer-policy: strict-origin-when-cross-origin
report-to: {"group":"heroku-nel","endpoints":[{"url":"https://nel.heroku.com/reports?s=5S%2BvRxdwNOJp%2FUHozjH0YNQ7D3Hx%2FvM9D3jxz2p5NGY%3D\u0026sid=e11707d5-02a7-43ef-b45e-2cf4d2036f7d\u0026ts=1753509996"}],"max_age":3600}
reporting-endpoints: heroku-nel="https://nel.heroku.com/reports?s=5S%2BvRxdwNOJp%2FUHozjH0YNQ7D3Hx%2FvM9D3jxz2p5NGY%3D&sid=e11707d5-02a7-43ef-b45e-2cf4d2036f7d&ts=1753509996"
server: cloudflare
strict-transport-security: max-age=0; includeSubDomains
vary: Accept,Accept-Encoding
via: 2.0 heroku-router
x-content-type-options: nosniff
x-permitted-cross-domain-policies: none
x-request-id: 5a3a12ed-4431-14c7-2806-a503a29f96e6
x-runtime: 0.127051
x-xss-protection: 0
content-encoding: gzip
set-cookie: _secure_speakerd_session=wFm1nmzqNIcu5cNarZ4Kf7KWS0kCZRr5CSM3Yifipv4g2CqJ9hQjMXYy%2FJO%2F%2Bc9EN%2FzcWKlWmEfYxzYG6GGlB2go8RdDX5uer54rpIAI8qAHH6Pt6C1WWxEEvzPC9J6auICxix%2BvnCOaPGcj0CWsoVEbz7GiPSxmeB787UgK5jPlm%2BO5xvt%2BuyjlyH2kZ54YmL2zJj3iiJm1cRMFANoeYG7LBmKpdEzOhp%2FwW9HHz0ZszUoTxR0jwUlrz5zatsG%2FscHJ6rFjwV%2BPyqe7uaNqL77QUahIyX%2Fdj88RfO8rP5dWnK52tFipsJG9U%2BzpVrVI3Kx1Tt5o2SBLiGJZBcTjVnf2PS0lEDUbzCnutFgfeSksy7XatxsM3rHeZBU1GCkw0VwZ3vbf1DlyKH7WbE0KK6F8--bpJjdU2H%2BzZKEgdk--0pkE4vZGP1uRMCMHSXchCg%3D%3D; HttpOnly; SameSite=Lax; Secure; Path=/; Expires=Sat, 09 Aug 2025 06:06:36 GMT
cf-ray: 9651b6411b40ccbb-BLR
Instant Loading with Service Workers (Chrome Dev Summit '15) - Speaker Deck
Instant Loading with Service Workers (Chrome Dev Summit '15)
Presentation video: https://www.youtube.com/watch?v=jCKZDTtUA2A
Service workers can power your web app while offline, but they can also offer substantial performance benefits while online. We’ll explain how to structure your web app to optimize load time for initial and return visitors, and cover helpful service worker libraries that minimize the amount of boilerplate code you’ll have to write.
Jeffrey Posnick
November 17, 2015
More Decks by Jeffrey Posnick
Other Decks in Technology
Featured
Transcript
-
ifixit-pwa.appspot.com 2G Network, second visit ~ 200ms for above-the-fold (~
560ms w/o service worker) -
ifixit-pwa.appspot.com 2G Network, new page ~ 225ms for above-the-fold (~
650ms w/o service worker) -
1 second delay in page times leads to 11% fewer
page views 16% decrease in customer satisfaction goo.gl/SOR47G -
Anatomy of an App Shell /shell HTML + styles.css Styles
app.js JavaScript = Shell -
The Life of a Service Worker No Service Worker install
Event ↪ Cache the App Shell! -
template placeholder Service Worker Installation site-wide styles Contents of /shell
site-wide JS <head> <style> /* inline styles */ </style> </head> <body> <!-- template insertion point --> <script src="app.js"> </body> Shell -
The Life of a Service Worker No Service Worker install
Event activate Event Idle fetch Event ↪ Cache Clean Up ↪ Handle Network Requests Stopped Stopped -
sw-precache for Your App Shell sw-precache + = github.com/GoogleChrome/sw-precache npm
install --save-dev sw-precache Shell -
sw-precache in Action Shell // [file, hash] pairs ... [js/app.js,
hashABC] ... [styles/all.css, hash123] // Service worker code service-worker.js build/{images,js,styles}/**/* -
sw-precache in Action: Updates Shell // [file, hash] pairs ...
[js/app.js, hashXYZ] ... [styles/all.css, hash789] // Service worker code service-worker.js -
sw-precache Command-line Interface Shell $ npm install -g sw-precache $
sw-precache --verbose Caching static resource "./images/back.png" (151 B) Caching static resource "./js/app.js" (319.06 kB) Caching static resource "./js/register-service-worker.js" (546 B) Caching static resource "./js/third-party.js" (245.03 kB) Caching static resource "./service-worker.js" (8.59 kB) Caching static resource "./styles/all.css" (1.82 kB) Total precache size is about 575.19 kB for 6 resources. service-worker.js has been generated with the service worker contents. -
gulp.babel.js Shell App Shell Template Partials/Inlines Request Redirection App Shell
External Styles/Images/JS sw-toolbox Import swPrecache.write('service-worker.js', { dynamicUrlToDependencies: { '/shell': [...glob.sync(`${BUILD_DIR}/rev/js/**/*.js`), ...glob.sync(`${BUILD_DIR}/rev/styles/all*.css`), `${SRC_DIR}/views/index.handlebars`] }, navigateFallback: '/shell', staticFileGlobs: [ `${BUILD_DIR}/rev/js/**/*.js`, `${BUILD_DIR}/rev/styles/all*.css`], importScripts: [`${BUILD_DIR}/sw/sw-toolbox.js`], }); -
Rein in Your Caches! Content toolbox.router.get( '/path/to/images/.*', toolbox.cacheFirst, {cache: {
name: 'images', maxEntries: 6 }} ); -
sw-toolbox-config.js Content iFixit API Route toolbox.fastest fallback logic Image Route
toolbox.cacheFirst LRU cache expiration toolbox.router.get('/api/2.0/(.*)', toolbox.fastest, { origin: /^https:\/\/www.ifixit.com$/ }); const MISSING_IMAGE = '/images/missing.png'; toolbox.cache(MISSING_IMAGE); function imageHandler(request, values, options) { return toolbox.cacheFirst(request, values, options).catch(() => { return caches.match(MISSING_IMAGE); }); } toolbox.router.get('/(.*)', imageHandler, { cache: {name: 'image-cache', maxEntries: 50}, origin: /cloudfront.net$/ }); -
if (‘serviceWorker’ in navigator) { navigator.serviceWorker.register(‘sw.js’); } else { //
But not all browsers // support service workers! } -
HTTP Caching Best Practices Still Apply ✓ Add hashes to
resource file names in your build ↪ /styles/all.css → /styles/all.ed34c56.css ✓ Use far-future HTTP caching headers ↪ Cache-Control: max-age=31536000 Still plays nicely with sw-precache! -
Service Workers FTW! But, service workers let you: ✓ Serve
the HTML for the landing page cache-first... ✓ ...even if that page is server-rendered.