Service workers and speed: caching, and what it costs
A service worker can make repeat visits fast and pages work offline, but it adds startup time and the risk of stale pages. How it works and when it is worth it.
In this guide
What a service worker is
MDN says service workers essentially act as proxy servers that sit between web applications, the browser and the network. A service worker is an event-driven script registered for an origin and a path. It can intercept navigation and resource requests, modify them, and cache resources with fine control. It runs in a worker context: no access to the page, and a thread of its own. Synchronous XHR and Web Storage cannot be used inside it, and dynamic import() is not allowed, although static imports are. Service workers only work on secure origins, so the site must use HTTPS, with http://localhost as the exception for development.
Its life has stages. The page registers it, the browser downloads and installs it, and then it activates and starts to handle requests. Because that happens after the page has loaded, a service worker cannot speed up a visitor's first visit. It helps on the visits that follow.
A service worker is not the same as an ordinary web worker. See web workers for those.
How it can make a site faster
- Repeat visits. It can answer from a cache without touching the network, so files are there at once.
- Pages that work offline or on a poor connection.
- Control the HTTP headers cannot give. The
Cacheinterface in a service worker is a high-level cache driven by JavaScript. The Workbox documentation stresses that it is separate from the HTTP cache: theCache-Controlheaders you use to steer the browser's HTTP cache have no influence on what a service worker stores. Think of the two as layers. See caching explained and HTTP caching headers. - Fast page loads for pages that rarely change. web.dev notes that a stale-while-revalidate strategy for documents that change rarely can make the time to first byte nearly instant, and that a streaming design, where parts of the page come from the cache and are combined with small pieces from the network, can do the same. For client-rendered applications, an app shell served from the cache gives an immediate frame, and the content fills in later.
What it costs
- Startup. MDN explains that a service worker cannot process events until it has booted. Usually this has little effect, because workers often stay running for a while and answer from a cache, which is fast. But when a worker has to boot before it can fetch from the network, the delay can be significant.
- Navigation preload is the fix. It lets the browser start the network request in parallel with the worker's start-up, so that the response may already be arriving when the worker is ready. MDN says this makes the case where the worker must start "no worse" than when it is already running. It works in Chrome 59 and later, Edge 18, Firefox 99 and Safari 15.4.
- Stale content. A cache that is never refreshed shows old pages. This is the most common problem, and visitors may not be able to fix it without clearing their data.
- Complexity. Updates, versions and edge cases are your job. A mistake can break the site for repeat visitors, who are your most loyal ones.
- Memory and processing time. A running worker uses both.
Caching strategies
A caching strategy is the way a service worker's fetch handler combines the network and the cache. Workbox, the library from the Chrome team, describes five:
| Strategy | What it does | Good for | Watch out for |
|---|---|---|---|
| Cache first | Answers from the cache, and goes to the network only when the file is missing | Files with a version in the name, fonts, logos | Stale files if the name does not change |
| Network first | Tries the network, and falls back to the cache | Pages that change often, data | A slow network makes the visitor wait |
| Stale-while-revalidate | Answers from the cache, then updates the cache from the network in the background | Content that matters but need not be the latest, such as avatars | Shows the previous version once |
| Network only | Always asks the network | Requests that must never be cached | No offline support |
| Cache only | Answers only from the cache | Files stored at install time | Fails if the file is not there |
Match the strategy to the content. Versioned static files can go cache first, in the same way as a long max-age with immutable. HTML is the sensitive one. It carries the links to the current files, so a stale page can point to files that no longer exist.
A starting point
The code below turns on navigation preload and splits the work in two. Pages come from the network first, using the preloaded response, with the cache as a fallback when the visitor is offline. Other files come from the cache first. It is adapted from the MDN documentation, and it leaves out the part that fills the cache, which you would do when the worker installs or as files are fetched:
// sw.js
addEventListener('activate', (event) => {
event.waitUntil((async () => {
if (self.registration.navigationPreload) {
await self.registration.navigationPreload.enable();
}
})());
});
addEventListener('fetch', (event) => {
const { request } = event;
event.respondWith((async () => {
if (request.mode === 'navigate') {
try {
return (await event.preloadResponse) || (await fetch(request));
} catch {
return (await caches.match(request)) || Response.error();
}
}
return (await caches.match(request)) || fetch(request);
})());
});For anything beyond this, a library is easier and safer than hand-written handlers. Workbox provides ready-made strategies and the code to manage the caches.
Update safely
- Version your caches (
site-v1,site-v2) and delete the old ones when the new worker activates. - Make sure the browser can see a new version of the worker script. If it never does, no fix can reach your visitors.
- Test the upgrade path. Visit the old version, then deploy the new one and visit again. This is where most bugs hide.
- Keep a way out. If the worker misbehaves, you need to be able to remove it. A replacement worker that clears the caches and unregisters itself is a common emergency plan.
When it is worth it
A service worker is worth the work for:
- an application that visitors open again and again, or one that must work offline;
- a content site with many repeat readers and pages that change rarely;
- a store that wants fast category pages and an offline fallback, if the personal parts are kept out of the cache.
It is probably not worth it for a brochure site with few repeat visits, for pages that are personalized, or when nobody on the team can maintain it. A first visit is the one most sites lose, and a service worker cannot change that. A fast server, a CDN and good headers help every visit.
How to measure it
- Lighthouse and PageSpeed Insights will not show the benefit. By default Lighthouse clears the page's storage before a run, including service workers and cache storage, so it always tests a first visit. Real-visitor data shows the effect over time.
- In Chrome DevTools, the Size column of the Network panel marks files served by the worker with
(ServiceWorker), and the Timing tab has phases for service worker start-up and for the request to the worker. - Test the repeat visit yourself in the Network panel, with a throttled connection, after the worker has installed.
Check your own page
Run the free audit, which tests a first visit. A service worker will not change that result, so its score tells you how your site performs for a new visitor. If most of your traffic is repeat visitors, look at the real-visitor numbers as well.
Sources
- Service Worker API and NavigationPreloadManager on MDN.
- Caching strategies overview in the Workbox documentation: the Cache interface, the fetch event and the five strategies.
- Optimize Time to First Byte on web.dev: stale-while-revalidate, streaming and the app shell.
- Network features reference in Chrome DevTools: the timing phases.
Start here
Free website audit
Live Google data for any public page: mobile and desktop.
Mobile + desktop · Lighthouse lab test · Real-user Chrome data when Google has it
Rather have this done for you? Speed optimization · Book a call