optimize caching

This commit is contained in:
corsacca 2026-05-20 16:39:58 +01:00
parent 1c6ad3b70e
commit b766825a64
3 changed files with 36 additions and 1 deletions

View file

@ -5,6 +5,23 @@
// routes — admin pages declare their own typography in admin.css.
const { locale, locales } = useI18n()
const { public: pub } = useRuntimeConfig()
// Warm DNS+TCP+TLS for the cross-origin services these pages hit: the prayer
// data API (people-group components) and the idle-loaded analytics + feedback
// widget scripts. Deriving from runtime config keeps these correct per env.
const preconnectOrigins = computed(() => {
const origins = new Set<string>()
for (const url of [pub.prayBaseUrl, pub.statinatorUrl, pub.feedbackApiBase]) {
if (!url) continue
try {
origins.add(new URL(String(url)).origin)
} catch {
// ignore malformed/empty url
}
}
return [...origins]
})
// Direction attribute per locale (Arabic = rtl)
const currentLocale = computed(() =>
@ -21,6 +38,7 @@ useHead(() => ({
dir: dir.value
},
link: [
...preconnectOrigins.value.map(origin => ({ rel: 'preconnect', href: origin })),
// Preload the heading font (Bebas Neue) — it renders the above-the-fold
// h1/h2 (the LCP text), so fetching it early avoids a swap flash.
{ rel: 'preload', as: 'font', type: 'font/woff2', href: '/assets/fonts/BebasNeue/BebasNeue-Regular.woff2', crossorigin: '' },

View file

@ -66,7 +66,16 @@ export default defineNuxtPlugin(() => {
injectScript().then(() => window.goStats?.pageview()).catch(() => {})
}
if (!isExcluded(useRoute().path)) firePageview()
// Defer the initial pageview's script injection until the browser is idle so
// the analytics bundle stays off the initial load critical path. SPA route
// changes (below) still fire immediately — they happen after load.
if (!isExcluded(useRoute().path)) {
if ('requestIdleCallback' in window) {
requestIdleCallback(() => firePageview(), { timeout: 3000 })
} else {
setTimeout(firePageview, 2000)
}
}
const router = useRouter()
router.afterEach((to, from) => {

View file

@ -109,6 +109,11 @@ export default defineNuxtConfig({
},
routeRules: {
// Content-hashed build assets never change under the same URL — cache forever.
'/_nuxt/**': { headers: { 'cache-control': 'public, max-age=31536000, immutable' } },
// Fonts/images use stable filenames, so avoid `immutable`: a 7-day cache
// still lets an overwritten asset propagate within a week.
'/assets/**': { headers: { 'cache-control': 'public, max-age=604800' } },
'/': { prerender: true },
'/adopt': { prerender: true },
'/pray': { prerender: true },
@ -132,6 +137,9 @@ export default defineNuxtConfig({
// server crashes on boot. The bun preset builds the output for Bun's own
// resolver. Run it with `bun run ./.output/server/index.mjs`.
preset: 'bun',
// Precompress public assets (JS/CSS/HTML/SVG/JSON) to .br and .gz at build
// time; the server serves the compressed variant when the client supports it.
compressPublicAssets: { brotli: true, gzip: true },
// Dev-only: use in-memory cache for the payload mount. The default fs
// driver can't represent both a leaf route ("/fr") and children of that
// route ("/fr/adopt") simultaneously — the first visit writes a file at