← Back to Blog

Your service worker might be caching problems instead of solving them

Your service worker might be caching problems instead of solving them

Service workers are one of the most powerful features in the modern web platform. They sit between your browser and the network, intercepting every request. They can cache assets for offline use, speed up repeat visits, and enable push notifications. They can also silently break your site in ways that are almost impossible to debug if you do not know what to look for.

The problem is that a service worker, once installed, persists. It runs even when the user is not on your site. It controls which version of your pages the browser sees. And if it is caching aggressively without a proper update strategy, your users might be stuck on an old version of your site without either of you knowing it.

The install-and-forget trap

Most service workers are generated by a framework or build tool. The developer enables PWA support, a service worker file appears, and nobody looks at it again. But that file is making decisions about every request your site handles.

A common configuration caches the entire application shell and serves it from cache on every visit. This is fast but it means the user sees the version that was cached on their first visit. If your service worker does not check for updates, or if the update logic has a bug, the user never sees your changes. You deploy a fix for a broken checkout flow and the customer keeps seeing the broken version because their service worker keeps serving the cached one.

What goes wrong

No skipWaiting. Without skipWaiting() in the activate handler, a new service worker version sits in a "waiting" state until the user closes every tab with your site. Some users never close tabs. They can run an outdated service worker for weeks.

Overly broad fetch handlers. A fetch handler that intercepts all requests and returns cached responses without checking for updates will serve stale content indefinitely. The cache-first strategy is appropriate for versioned static assets (images, hashed JS bundles) but dangerous for HTML pages and API responses.

No offline fallback. If the service worker intercepts navigation requests but the cache is empty (first visit, cleared cache), the user gets a browser error page instead of a meaningful offline message.

Missing navigation preload. Without navigation preload enabled, the browser waits for the service worker to boot before making the network request. On mobile, service worker startup can add 200 to 500 milliseconds to every navigation.

What the audit checks

The Service Worker Audit fetches your service worker file and inspects the actual code. It checks:

Whether skipWaiting() is called so new versions activate immediately. Whether the fetch handler uses appropriate caching strategies for different resource types. Whether there is an offline fallback page. Whether navigation preload is enabled. Whether the install handler caches a reasonable set of assets without trying to cache everything.

It flags the specific patterns that cause the most real-world problems and explains why each one matters.

Why most sites get this wrong

Service workers require thinking about state in ways that web developers are not accustomed to. A regular web page is stateless from the user's perspective. You visit, you see the current version, you leave. A service worker adds persistent state. It remembers things between visits. It makes decisions about what the user sees based on what was cached previously.

This is powerful but it requires discipline. The cache needs a versioning strategy. The fetch handler needs different policies for different resource types. The update flow needs to handle the transition from old version to new version gracefully.

If you are building a site that needs to work offline or load instantly on repeat visits, as I cover in The $20 Dollar Agency, getting the service worker right is worth the time. Getting it wrong means your users are stuck on a version you have already fixed.

Fact-check notes and sources

  • Service worker startup latency on mobile: 200-500ms typical. Source: Google Web Fundamentals, "Service Worker Lifecycle" documentation.
  • Navigation preload was introduced in Chrome 59. Source: Chrome Platform Status (chromestatus.com).
  • The skipWaiting() + clients.claim() pattern is recommended by Google for immediate activation. Source: web.dev/articles/service-workers-lifecycle.

Related reading

This post is informational, not web development consulting advice. Mentions of Google and Chrome are nominative fair use. No affiliation is implied.

← Back to Blog

Accessibility Options

Text Size
High Contrast
Reduce Motion
Reading Guide
Link Highlighting
Accessibility Statement

J.A. Watte is committed to ensuring digital accessibility for people with disabilities. This site conforms to WCAG 2.1 and 2.2 Level AA guidelines.

Measures Taken

  • Semantic HTML with proper heading hierarchy
  • ARIA labels and roles for interactive components
  • Color contrast ratios meeting WCAG AA (4.5:1)
  • Full keyboard navigation support
  • Skip navigation link
  • Visible focus indicators (3:1 contrast)
  • 44px minimum touch/click targets
  • Dark/light theme with system preference detection
  • Responsive design for all devices
  • Reduced motion support (CSS + toggle)
  • Text size customization (14px–20px)
  • Print stylesheet

Feedback

Contact: jwatte.com/contact

Full Accessibility StatementPrivacy Policy

Last updated: April 2026