Reputation: 1735
I understand that ServiceWorkers can grab responses out of cached network requests.
That said, is it possible to have these workers continue to update the cache in the background?
Consider the following scenario: a user logs into an app where they have cached data, and is immediately greeted with "Welcome, <cached_username>!"
Is it be possible for the service worker to continue to make the network request after serving a cache match? The user could've updated their username to new_username
on another device, and it would be great to get the UI eventually consistent.
I still want to make network requests, while also utilizing ServiceWorkers for that speedy initial render.
Upvotes: 1
Views: 1069
Reputation: 56144
What you're describing is very similar to the stale-while-revalidate strategy.
The basic recipe in that cookbook doesn't include any code for having the service worker notify the client page(s) when the revalidation step finds an update, though.
If you were to use Workbox inside your service worker, you could accomplish that notification step using the workbox-broadcast-update
module along with a few other modules:
In your service worker:
import {registerRoute} from 'workbox-routing';
import {StaleWhileRevalidate} from 'workbox-strategies';
import {BroadcastUpdatePlugin} from 'workbox-broadcast-update';
registerRoute(
// Adjust this to match your cached data requests:
new RegExp('/api/'),
new StaleWhileRevalidate({
plugins: [
new BroadcastUpdatePlugin(),
],
})
);
In your web app:
navigator.serviceWorker.addEventListener('message', async (event) => {
// Optional: ensure the message came from workbox-broadcast-update
if (event.data.meta === 'workbox-broadcast-update') {
const {cacheName, updatedUrl} = event.data.payload;
// Do something with cacheName and updatedUrl.
// For example, get the cached content and update
// the content on the page.
const cache = await caches.open(cacheName);
const updatedResponse = await cache.match(updatedUrl);
const updatedText = await updatedResponse.text();
}
});
Upvotes: 1