From 734ba68eeda073406e550845ca6fcf270e6a2d38 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 13 Apr 2026 21:34:02 +0500 Subject: [PATCH] perf: cache translated chapter responses for 1 hour MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Translation content is immutable once generated — add Cache-Control: public, max-age=3600, stale-while-revalidate=86400 to handleTranslationRead so the browser and any CDN reuse the response without hitting MinIO on repeat views. Forward the header through the SvelteKit /api/translation/[slug]/[n] proxy which previously stripped it by constructing a bare Content-Type-only Response. --- backend/internal/backend/handlers.go | 4 ++++ ui/src/routes/api/translation/[slug]/[n]/+server.ts | 9 ++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/backend/internal/backend/handlers.go b/backend/internal/backend/handlers.go index 150fca1..d3bda3c 100644 --- a/backend/internal/backend/handlers.go +++ b/backend/internal/backend/handlers.go @@ -1279,6 +1279,10 @@ func (s *Server) handleTranslationRead(w http.ResponseWriter, r *http.Request) { return } + // Translated chapter content is immutable once generated — cache aggressively. + // The browser and any intermediary (CDN, SvelteKit fetch cache) can reuse this + // response for 1 hour without hitting MinIO again. + w.Header().Set("Cache-Control", "public, max-age=3600, stale-while-revalidate=86400") writeJSON(w, 0, map[string]string{"html": buf.String(), "lang": lang}) } diff --git a/ui/src/routes/api/translation/[slug]/[n]/+server.ts b/ui/src/routes/api/translation/[slug]/[n]/+server.ts index 4fb6d09..5492a39 100644 --- a/ui/src/routes/api/translation/[slug]/[n]/+server.ts +++ b/ui/src/routes/api/translation/[slug]/[n]/+server.ts @@ -23,9 +23,12 @@ export const GET: RequestHandler = async ({ params, url }) => { return new Response(null, { status: res.status }); } const data = await res.json(); - return new Response(JSON.stringify(data), { - headers: { 'Content-Type': 'application/json' } - }); + const headers: Record = { 'Content-Type': 'application/json' }; + // Forward the immutable cache header from the backend so browsers and CDNs + // can cache translated chapter content without hitting MinIO on every load. + const cc = res.headers.get('Cache-Control'); + if (cc) headers['Cache-Control'] = cc; + return new Response(JSON.stringify(data), { headers }); }; export const POST: RequestHandler = async ({ params, url, locals }) => {