Refine caching behavior in service worker

This commit is contained in:
Adrian Gruntkowski 2024-11-30 23:15:03 +01:00
parent 6c3bfd5a9a
commit 1dec90e0a2

View file

@ -1,42 +1,68 @@
// caching // caching
const putInCache = async (request, response) => { const cacheName = "jenot-v1";
const cache = await caches.open("v1"); const appShellFiles = [
await cache.put(request, response); "/index.html",
}; "/style.css",
"/img/android-chrome-192x192.png",
"/img/android-chrome-512x512.png",
"/img/apple-touch-icon.png",
"/img/favicon.ico",
"/img/favicon-16x16.png",
"/img/favicon-32x32.png",
"/js/components.js",
"/js/dom.js",
"/js/jenot.js",
"/js/notifications.js",
"/js/service-worker-init.js",
"/js/synced-store.js",
];
const cacheFirst = async ({ request, fallbackUrl }) => { const cacheFirst = async (e) => {
const responseFromCache = await caches.match(request); const responseFromCache = await caches.match(e.request);
if (responseFromCache) { if (responseFromCache) {
return responseFromCache; return responseFromCache;
} }
try { const responseFromNetwork = await fetch(e.request);
const responseFromNetwork = await fetch(request);
// Cloning is needed because a response can only be consumed once. // Cloning is needed because a response can only be consumed once.
putInCache(request, responseFromNetwork.clone()); caches
.open(cacheName)
.then((cache) => cache.put(e.request, responseFromNetwork.clone()));
return responseFromNetwork; return responseFromNetwork;
} catch (error) {
const fallbackResponse = await caches.match(fallbackUrl);
if (fallbackResponse) {
return fallbackResponse;
}
return new Response("Network error happened", {
status: 408,
headers: { "Content-Type": "text/plain" },
});
}
}; };
self.addEventListener("fetch", (event) => { self.addEventListener("install", (e) => {
// We don't cache API requests e.waitUntil(
if (!event.request.url.pathname.startsWith("/api")) { caches
event.respondWith( .open(cacheName)
cacheFirst({ .then((cache) => cache.addAll(appShellFiles))
request: event.request, .then(() => self.skipWaiting()),
fallbackUrl: "/index.html", );
});
self.addEventListener("activate", (e) => {
e.waitUntil(
caches
.keys()
.then((keyList) => {
return Promise.all(
keyList.map((key) => {
if (key === cacheName) {
return;
}
return caches.delete(key);
}), }),
); );
} })
.then(() => self.clients.claim()),
);
});
self.addEventListener("fetch", (event) => {
if (event.request.url.pathname.startsWith("/api")) {
return;
}
event.respondWith(cacheFirst(event));
}); });