I want to use a service worker to precache a webpage on install.
It is very easy to precache the HTML itself
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open('v1')
.then((cache) => {
return cache.addAll(['/404.html']);
})
);
});
But! When the browser loads the 404.html page, it also fetches a lot of dependencies from other URLs, like scripts, stylesheets, images, fonts, etc.
How can my service worker fetch and precache those dependency resources too?
I don't want to manually list and track the dependencies
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open('v1').then((cache) => {
return cache.addAll([
'/404.html',
'/static/css/main.css',
'/static/css/404.css',
'/static/img/logo.png',
'/static/fonts/inter-var.woff2',
// ... everything the offline page needs
]);
})
);
});
Because the site has a lot of cache-busted filenames (e.g., main.abc123.css) that get programmatically generated every so often, so hardcoding won't work, and I don't want to risk forgetting to manually add a new dependency (or remove an obsolete one) from this list. I imagine I'd have to orchestrate something very complicated (like playwright-generating the real list of dependencies) to support a list of dependencies like this.
I think parsing the HTML in the service worker is not a good solution either, because it doesn't handle CSS url() references, dynamic URLs (e.g. JS-generated ones), unless there's a browser API for it that fetches the page under the hood (that I don't know about yet), implementing my own in-the-browser parser sounds like asking for nightmares! It would be fragile and probably not maintain accurate parity with a real browser.
fetch, see usage: developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch