Sign in
Topics

Build and launch your progressive web apps quickly
Learn how to make the service worker cache data from an API and update the cache when needed—so your app can stay responsive, consistent, and ready for whatever the network throws at it.
When a web app feels instant, reliable, and works even when the network drops, users notice—and they stick around.
Behind that smooth experience is often a quiet background hero: the service worker, which acts as an invisible bridge between your web app and the network, storing resources locally, serving them instantly, and updating them when fresh data is available.
If you’ve ever wondered why some progressive web apps load as fast on a train with spotty Wi-Fi as they do in a high-speed office connection, the answer lies in smart caching strategies.
A progressive web app depends on a service worker to act as a middle layer between the web app and the network. The service worker runs in the background, caching static assets and API responses to let the app load offline and respond swiftly when the network is slow. In modern browsers, the service worker handles fetch requests and delivers cached content when needed. Browsers rely on the service worker lifecycle—from service worker installation to activation—to manage updates and the cache behavior smoothly.
“How would you build for users with no internet?”
That was one of the most interesting questions I got in a recent interview, and it stuck with me. As developers, we often assume good connectivity. But the real world isn’t always so kind.— Check out full post here
It intercepts fetch events to serve cached assets or fetch fresh data. It’s the service worker’s job to improve performance and reliability by caching resources, including API responses, enabling offline access.
Caching data ensures that the web app still functions when the user opens it without a network. It lowers the load on the server and speeds up subsequent visits.
Start by creating a service worker file and registering it in the web app’s main script. You need to write service worker registration code to integrate the service worker into the progressive web app lifecycle.
Service worker registration takes place in your main JavaScript, typically:
1if ('serviceWorker' in navigator) { 2 window.addEventListener('load', () => { 3 navigator.serviceWorker.register('/sw.js') 4 .then(reg => console.log('service worker installed', reg)) 5 .catch(err => console.error('registration failed', err)); 6 }); 7}
This ensures the new service worker is registered once the page loads. The existing service worker, if any, will be replaced following the service worker lifecycle, once the new service worker installation completes.
Your service worker file handles the install event and the fetch event. During service worker installation, cache API data and static assets.
1const CACHE_NAME = 'api-cache-v1'; 2const urlsToCache = [ 3 '/', 4 '/styles.css', 5]; 6 7self.addEventListener('install', event => { 8 console.log('install event triggered'); 9 event.waitUntil( 10 caches.open(CACHE_NAME) 11 .then(cache => { 12 return cache.addAll(urlsToCache); 13 }) 14 ); 15});
In this install event, the service worker was installed into the browser and cached static files. It supports offline capabilities by storing static assets.
Write the fetch event handler in your service worker code to intercept network requests:
1self.addEventListener('fetch', event => { 2 const requestUrl = new URL(event.request.url); 3 4 if (requestUrl.pathname.startsWith('/api/data')) { 5 event.respondWith( 6 caches.open(CACHE_NAME).then(cache => 7 cache.match(event.request).then(response => { 8 const fetchPromise = fetch(event.request).then(networkResponse => { 9 cache.put(event.request, networkResponse.clone()); 10 return networkResponse; 11 }); 12 return response || fetchPromise; 13 }) 14 ) 15 ); 16 } else { 17 event.respondWith( 18 caches.match(event.request).then(response => { 19 return response || fetch(event.request); 20 }) 21 ); 22 } 23});
This fetch event handler looks for requests to /api/data, opens the cache, returns cached response if available, and meanwhile fetches fresh data to update the cache. It uses a network plus cache strategy, ensuring the user gets cached data first, followed by the latest data if available. That approach improves responsiveness for offline use.
Here’s a Mermaid diagram that visually represents your fetch event handler logic:
This diagram shows:
How the /api/data path triggers the API-specific caching logic.
The cache-first with network update approach.
How other requests fall back to a simpler cache-first strategy for static assets.
I can create a second diagram illustrating the network-first approach with cache fallback, allowing your readers to compare caching strategies visually. That would make the blog even more complete.
When you deploy a new version of the service worker file, browsers detect the change in the service worker code and trigger installation for the new service worker. The old service worker remains active until all pages controlled by it close. After activation, the new service worker takes over.
After a successful installation event and activation, the new service worker becomes the active service worker. To manage versioned cache, you might introduce:
1self.addEventListener('activate', event => { 2 const newCache = CACHE_NAME; 3 event.waitUntil( 4 caches.keys().then(keys => 5 Promise.all( 6 keys.filter(key => key !== newCache).map(key => caches.delete(key)) 7 ) 8 ) 9 ); 10});
This ensures stale caches from the old service worker are cleaned up when the new service worker activates, preventing storage bloat.
A well-written service worker still needs careful testing and observation to ensure it behaves exactly as intended. Modern browsers offer built-in developer tools that make it straightforward to monitor the service worker lifecycle, debug caching issues, and confirm that the right resources are being served.
In Chrome DevTools, you can open the Application panel and navigate to the Service Workers section. Here, you’ll see the status of the installed and active service worker, along with options to:
Force update the service worker to test how a new version behaves.
Skip waiting, which activates a new service worker immediately rather than waiting for the old service worker to release control.
Unregister a service worker completely, which is useful if you need to reset everything during testing.
Just below that, the Cache Storage tab shows a complete list of your service worker cache entries. You can:
Expand a specific cache to inspect all cached requests and responses.
Verify whether API data, static assets, or other files are stored as expected.
Delete individual cached items or clear the entire cache to simulate a fresh install event.
For Microsoft Edge, the steps are similar since it’s based on Chromium. Other browsers, like Firefox, offer comparable tools with their layouts. By regularly inspecting these areas, you can quickly identify mismatched cache keys, confirm that the fetch event handler is intercepting requests correctly, and ensure your progressive web app is truly serving the best possible experience.
Want to speed up app development process?
With Rocket.new you can build and ship progressive web apps rapidly, without extra overhead. Start building smarter, faster, and with confidence.
While our focus is on front-end service worker caching, you might address backend caching. How to enable cache on APIs using Spring Cache? In Spring (Java), you add @Cacheable on methods and configure a cache store like Redis. But that is separate from the service worker cache.
Similarly, adding caching to the API gateway, such as using caching filters in Spring Cloud Gateway or an API gateway like Amazon API Gateway, provides server-side caching enhancements, which complement the client-side service worker cache.
Version your cache names for new cache management.
Limit cached API data size.
Set expiration for cached assets.
Use proper fetch event strategy: cache-first for static assets, network-first for API, with fallback to cache.
Keep the service worker file small and lean.
Test on multiple operating systems, web browsers, and devices, including Microsoft Edge.
In this blog, you learned how to make the service worker cache data from api and update the cache when needed by leveraging install and fetch events, proper registration, and lifecycle management. Implementing a network-first or cache-first strategy can greatly improve the reliability and performance of your progressive web app. Keep iterating, monitor behavior across web browsers and operating systems, and refine your service worker code to deliver a seamless user experience—even when the network isn’t dependable.