From 582246f910f8f3a2d0b444b06829f6f8b1c32a6d Mon Sep 17 00:00:00 2001 From: Benjamin Milde Date: Tue, 31 Dec 2024 11:48:15 +0100 Subject: [PATCH] Cache video.js in background and require it only where needed --- assets/js/app.js | 13 ++++ assets/js/serviceworker.js | 69 +++++++++++++++++++ config/config.exs | 2 +- .../components/layouts/root.html.heex | 8 ++- lib/kobrakai_web/endpoint.ex | 10 ++- lib/kobrakai_web/router.ex | 2 +- .../views/page_html/home.html.heex | 6 +- 7 files changed, 105 insertions(+), 5 deletions(-) create mode 100644 assets/js/serviceworker.js diff --git a/assets/js/app.js b/assets/js/app.js index 860b946..fec4c3c 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -55,3 +55,16 @@ liveSocket.connect(); window.liveSocket = liveSocket; handleDarkMode(); + +if ("serviceWorker" in navigator) { + // Register a service worker hosted at the root of the + // site using the default scope. + navigator.serviceWorker + .register("/assets/serviceworker.js", { scope: "/" }) + .then( + (registration) => console.log("Service worker registration succeeded."), + (error) => console.error(`Service worker registration failed: ${error}`), + ); +} else { + console.error("Service workers are not supported."); +} diff --git a/assets/js/serviceworker.js b/assets/js/serviceworker.js new file mode 100644 index 0000000..6d4fb15 --- /dev/null +++ b/assets/js/serviceworker.js @@ -0,0 +1,69 @@ +"use strict"; + +const version = "20241231"; +const staticCacheName = "static-" + version; +const cacheList = [staticCacheName]; + +async function updateStaticCache() { + let staticCache = await caches.open(staticCacheName); + staticCache.addAll([ + "/assets/video.js", + "/assets/app.css", + "/assets/app.js", + "/images/signee.png", + "/images/pfeil.png", + "/images/avatar.jpg", + "/font/noway-regular-webfont.woff", + "/font/noway-regular-webfont.woff2", + "/font/Virgil.woff2", + ]); +} + +async function clearOldCaches() { + let keys = await caches.keys(); + return Promise.all( + keys + .filter((key) => !cacheList.includes(key)) + .map((key) => caches.delete(key)), + ); +} + +addEventListener("install", (installEvent) => { + installEvent.waitUntil(updateStaticCache()); + skipWaiting(); +}); + +addEventListener("activate", (activateEvent) => { + activateEvent.waitUntil(clearOldCaches()); + clients.claim(); +}); + +addEventListener("fetch", (fetchEvent) => { + let request = fetchEvent.request; + let url = new URL(request.url); + + // Only deal with requests to my own server + if (url.origin !== location.origin) { + return; + } + + // Only deal with GET requests + if (request.method !== "GET") { + return; + } + + // For HTML requests, try the preload first, then network, fall back to the cache, finally the offline page + if ( + request.mode === "navigate" || + request.headers.get("Accept").includes("text/html") + ) { + return; + } + + // For non-HTML requests, look in the cache first, fall back to the network + fetchEvent.respondWith( + caches.match(request).then((responseFromCache) => { + return responseFromCache || fetch(request); + }), + ); +}); diff --git a/config/config.exs b/config/config.exs index 718fb19..a7ec87f 100644 --- a/config/config.exs +++ b/config/config.exs @@ -36,7 +36,7 @@ config :bun, install: [args: ~w(install), cd: Path.expand("../assets", __DIR__), env: %{}], default: [ args: - ~w(build js/app.js js/storybook.js js/video.js --format=iife --outdir=../priv/static/assets --external /fonts/* --external /images/*), + ~w(build js/app.js js/storybook.js js/video.js js/serviceworker.js --format=iife --outdir=../priv/static/assets --external /fonts/* --external /images/*), cd: Path.expand("../assets", __DIR__), env: %{} ], diff --git a/lib/kobrakai_web/components/layouts/root.html.heex b/lib/kobrakai_web/components/layouts/root.html.heex index 178787c..0529d35 100644 --- a/lib/kobrakai_web/components/layouts/root.html.heex +++ b/lib/kobrakai_web/components/layouts/root.html.heex @@ -19,7 +19,13 @@ -