1
0
mirror of https://github.com/osmarks/website synced 2024-11-09 20:49:55 +00:00

Service-worker-based prefetch

This commit is contained in:
osmarks 2024-04-30 16:30:27 +01:00
parent 943152a1e6
commit ed52fa9c24
4 changed files with 54 additions and 17 deletions

8
src/common.js Normal file
View File

@ -0,0 +1,8 @@
export const ignorePaths = [
"/isso",
"/infipage",
"/wsthing",
"/random-stuff",
"/radio",
"/ystat"
]

View File

@ -374,6 +374,19 @@ const compilePageJSTask = async () => {
}) })
} }
const compileServiceWorkerJSTask = async () => {
await esbuild.build({
entryPoints: [ path.join(srcDir, "sw.js") ],
bundle: true,
outfile: path.join(outDir, "sw.js"),
minify: true,
sourcemap: true,
define: {
"siteVersion": JSON.stringify(globalData.buildID)
}
})
}
const genServiceWorker = async () => { const genServiceWorker = async () => {
const serviceWorker = mustache.render(await readFile(path.join(assetsDir, "sw.js")), globalData) const serviceWorker = mustache.render(await readFile(path.join(assetsDir, "sw.js")), globalData)
await minifyJSFile(serviceWorker, "sw.js", path.join(outDir, "sw.js")) await minifyJSFile(serviceWorker, "sw.js", path.join(outDir, "sw.js"))
@ -440,7 +453,7 @@ const tasks = {
manifest: { deps: ["assetsDir"], fn: genManifest }, manifest: { deps: ["assetsDir"], fn: genManifest },
minifyJS: { deps: ["assetsDir"], fn: minifyJSTask }, minifyJS: { deps: ["assetsDir"], fn: minifyJSTask },
compilePageJS: { deps: ["assetsDir"], fn: compilePageJSTask }, compilePageJS: { deps: ["assetsDir"], fn: compilePageJSTask },
serviceWorker: { deps: [], fn: genServiceWorker }, serviceWorker: { deps: [], fn: compileServiceWorkerJSTask },
images: { deps: ["assetsDir"], fn: doImages }, images: { deps: ["assetsDir"], fn: doImages },
offlinePage: { deps: ["assetsDir", "pagedeps"], fn: () => applyTemplate(globalData.templates.experiment, path.join(assetsDir, "offline.html"), () => path.join(outAssets, "offline.html"), {}) }, offlinePage: { deps: ["assetsDir", "pagedeps"], fn: () => applyTemplate(globalData.templates.experiment, path.join(assetsDir, "offline.html"), () => path.join(outAssets, "offline.html"), {}) },
assets: { deps: ["manifest", "minifyJS", "serviceWorker", "images", "compilePageJS"] }, assets: { deps: ["manifest", "minifyJS", "serviceWorker", "images", "compilePageJS"] },

View File

@ -1,22 +1,46 @@
const idb = require("idb") const idb = require("idb")
const { solve } = require("yalps") const { solve } = require("yalps")
const { ignorePaths } = require("./common")
const prefetchHook = () => {
let lastFetch = 0
const prefetch = event => {
if (Date.now() - lastFetch >= 200) {
const href = new URL(event.target.getAttribute("href"), window.location)
if (href.origin === window.location.origin) {
for (const ignorePath of ignorePaths) {
if (href.pathname.startsWith(ignorePath)) return
}
console.log("prefetch", href.href)
fetch(href)
lastFetch = Date.now()
}
}
}
for (const node of document.querySelectorAll("a[href]")) {
node.addEventListener("touchstart", prefetch)
node.addEventListener("mouseover", prefetch)
}
}
// attempt to register service worker // attempt to register service worker
if ("serviceWorker" in navigator) { if ("serviceWorker" in navigator) {
navigator.serviceWorker.register("/sw.js", { scope: "/" }).then(reg => { navigator.serviceWorker.register("/sw.js", { scope: "/" }).then(reg => {
if (reg.installing) { if (reg.installing) {
console.log("Service worker installing"); console.log("Service worker installing")
} else if (reg.waiting) { } else if (reg.waiting) {
console.log("Service worker installed"); console.log("Service worker installed")
} else if (reg.active) { } else if (reg.active) {
console.log("Service worker active"); console.log("Service worker active")
prefetchHook()
} }
}).catch(error => { }).catch(error => {
// registration failed // registration failed
console.log("Registration failed with " + error); console.log("Registration failed with " + error)
}); });
} else { } else {
console.log("Service workers are not supported."); console.log("Service workers are not supported.")
} }
// https://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript // https://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript

View File

@ -1,4 +1,5 @@
const siteVersion = "{{buildID}}" import { ignorePaths } from "./common"
const offlinePage = "/assets/offline.html" const offlinePage = "/assets/offline.html"
const cacheName = `${siteVersion}-v1` const cacheName = `${siteVersion}-v1`
const precache = [ const precache = [
@ -33,15 +34,6 @@ self.addEventListener("activate", event => {
) )
}) })
const ignorePaths = [
"/isso",
"/infipage",
"/wsthing",
"/random-stuff",
"/radio",
"/ystat"
]
const shouldRespond = req => { const shouldRespond = req => {
if (req.method !== "GET") { return false } // do not respond to non-GET requests if (req.method !== "GET") { return false } // do not respond to non-GET requests
if (!req.url.startsWith(self.location.origin)) { return false } // do not respond to cross-origin requests if (!req.url.startsWith(self.location.origin)) { return false } // do not respond to cross-origin requests