From 8c0a6ccf7fba31ad71457c355028fae679b0501b Mon Sep 17 00:00:00 2001 From: m5r Date: Sat, 4 Jun 2022 15:48:37 +0200 Subject: [PATCH] cache static assets --- app/service-worker/cache-utils.ts | 32 +++++++++++++++++++++++++++++++ app/service-worker/fetch.ts | 11 +++++++---- 2 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 app/service-worker/cache-utils.ts diff --git a/app/service-worker/cache-utils.ts b/app/service-worker/cache-utils.ts new file mode 100644 index 0000000..b31c2be --- /dev/null +++ b/app/service-worker/cache-utils.ts @@ -0,0 +1,32 @@ +import type { FetchEventWithPreloadResponse } from "./fetch"; + +export const ASSET_CACHE = "asset-cache"; + +export async function cacheAsset(event: FetchEventWithPreloadResponse) { + const url = new URL(event.request.url); + const cachedResponse = await caches.match(event.request, { + cacheName: ASSET_CACHE, + ignoreVary: true, + ignoreSearch: true, + }); + + console.debug(`Serving asset from ${cachedResponse ? "cache" : " network"}`, url.pathname); + + const fetchPromise = (async () => { + const cache = await caches.open(ASSET_CACHE); + const preloadedResponse = await event.preloadResponse; + const response = preloadedResponse || (await fetch(event.request)); + switch (response.status) { + case 200: + cache.put(event.request, response.clone()); + break; + case 404: + cache.delete(event.request); + break; + } + + return response; + })(); + + return cachedResponse || fetchPromise; +} diff --git a/app/service-worker/fetch.ts b/app/service-worker/fetch.ts index ad2355b..b49fbfc 100644 --- a/app/service-worker/fetch.ts +++ b/app/service-worker/fetch.ts @@ -1,9 +1,12 @@ +import { ASSET_CACHE, cacheAsset } from "~/service-worker/cache-utils"; + declare let self: ServiceWorkerGlobalScope; -export default async function handleFetch(event: FetchEvent & { preloadResponse?: Promise }) { - const preloaded = await event.preloadResponse; - if (preloaded) { - return preloaded; +export type FetchEventWithPreloadResponse = FetchEvent & { preloadResponse?: Promise }; + +export default async function handleFetch(event: FetchEventWithPreloadResponse) { + if (["font", "image", "script", "style"].includes(event.request.destination)) { + return cacheAsset(event); } return fetch(event.request);