Build Offline‑First Apps with Chrome Service Workers: A Practical Guide
Learn how Chrome’s Service Workers let you intercept network requests, cache assets, and deliver offline experiences. Follow a step‑by‑step example, see common pitfalls, and get actionable tips for production.
04 Sept 2026, 10:55 UTC

The Problem: Why Offline Matters
Modern web apps expect a constant internet connection, but users often face flaky networks, roaming data limits, or complete outages. An offline‑first strategy keeps the user experience smooth by serving cached content when the network is unavailable. Chrome’s Service Workers give you the control to decide what to cache, when to update it, and how to handle stale data.
Service Workers 101
A Service Worker is a JavaScript file that runs in a background thread, separate from the main page. It sits between your web app and the network, intercepting requests and deciding whether to fetch from the cache or from the network. Because it runs on a dedicated thread, it can also receive push notifications and perform background sync.
Lifecycle Overview
- install – run once when the SW is first registered or when the script changes. Good place to pre‑cache assets.
- activate – run after install, before the SW takes control of pages. Useful for cleaning old caches.
- fetch – fired on every network request made by pages under its scope.
Security Constraints
Service Workers must be served over HTTPS (or localhost) to prevent man‑in‑the‑middle attacks. In development, you can use localhost or a self‑signed certificate.
A Concrete Example – Caching a Single Asset
Project Setup
Create a minimal project structure:
index.html
service-worker.js
assets/
logo.png
Writing the Service Worker
Open service-worker.js and add the following:
const CACHE_NAME = 'offline-cache-v1';
const OFFLINE_URL = '/assets/logo.png';
// Install: pre‑cache a single asset
self.addEventListener('install', event => {
event.waitUntil(
caches.open(CACHE_NAME).then(cache => cache.add(OFFLINE_URL))
);
});
// Activate: clean old caches
self.addEventListener('activate', event => {
event.waitUntil(
caches.keys().then(keys =>
Promise.all(keys.filter(key => key !== CACHE_NAME).map(key => caches.delete(key)))
)
);
});
// Fetch: serve cached asset or fallback to network
self.addEventListener('fetch', event => {
const url = new URL(event.request.url);
if (url.pathname === OFFLINE_URL) {
event.respondWith(
caches.match(OFFLINE_URL).then(cached => cached || fetch(event.request))
);
}
});
Explanation of key parts:
CACHE_NAMEis versioned so you can invalidate old caches.- The
installevent pre‑cacheslogo.png. - The
activateevent removes caches that don’t match the current version. - The
fetchevent serves the cached asset when requested.
Registering and Testing
- In
index.html, register the Service Worker:<script> if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/service-worker.js'); } </script> - Open Chrome, go to
chrome://inspect/#service-workersor the Application panel under DevTools. Verify the SW is activated. - Disable network (offline mode in DevTools). Reload the page and confirm
logo.pngloads from cache. - Re‑open the network tab and check that the request shows
from Service Workeras the source.
Common Trade‑offs and Pitfalls
Cache Invalidation
Without a versioned CACHE_NAME or a proper invalidation strategy, users may see stale assets. Use a hash of the file contents or a timestamp in the cache name to force updates.
Script Size and Startup
Large Service Worker scripts delay the install event and increase memory usage. Keep the script lean, and consider splitting logic into separate modules if you have many caching rules.
Debugging Tips
- Service Worker errors appear in the DevTools Console but not in the page console.
- Use the Service Workers panel to inspect event logs, cache contents, and to unregister or skip waiting.
- Enable
debuggerstatements in the SW script to pause duringinstallorfetchevents.
Actionable Take‑aways
- Always serve Service Workers over HTTPS or localhost.
- Version your cache names and clean old caches in
activate. - Use Chrome DevTools’ Service Workers panel to monitor lifecycle events and inspect caches.
- For complex caching strategies, consider libraries like Workbox which provide runtime caching, background sync, and precaching helpers.
- Test offline scenarios by toggling the network in DevTools or using a network emulator.
By following this pattern, you can give your users a resilient, offline‑first experience while keeping the Service Worker lean and maintainable.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.