From 9d0da5d65ac6d0e2fbe546ba3e4c87a9204035b2 Mon Sep 17 00:00:00 2001 From: openhands Date: Wed, 26 Aug 2026 15:06:16 +0200 Subject: [PATCH] Perf: cache Nitro client assets and parallelize client page - Serve /swf and /nitro-assets (~2.8GB) with 7-day Cache-Control plus stale-while-revalidate so client opens stop re-fetching hundreds of files while asset updates still propagate in the background - Issue the SSO ticket and the online count query in parallel on the client page to shave a round-trip off the critical render path --- next.config.ts | 22 ++++++++++++++++++++++ src/app/client/page.tsx | 20 ++++++++++++-------- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/next.config.ts b/next.config.ts index 68fbf945..0ee59b6f 100644 --- a/next.config.ts +++ b/next.config.ts @@ -125,6 +125,28 @@ const nextConfig: NextConfig = { }, ], }, + { + // Nitro client payload (~2.8GB across swf/nitro-assets): without + // caching every client open re-downloads hundreds of files. + // Fresh for 7 days, then serve stale + revalidate in background + // so asset updates still propagate without blocking players. + source: "/swf/(.*)", + headers: [ + { + key: "Cache-Control", + value: "public, max-age=604800, stale-while-revalidate=2592000", + }, + ], + }, + { + source: "/nitro-assets/(.*)", + headers: [ + { + key: "Cache-Control", + value: "public, max-age=604800, stale-while-revalidate=2592000", + }, + ], + }, { source: "/images/(.*)", headers: [{ key: "Cache-Control", value: "public, max-age=86400" }], diff --git a/src/app/client/page.tsx b/src/app/client/page.tsx index c5dd1f52..ce7d8240 100644 --- a/src/app/client/page.tsx +++ b/src/app/client/page.tsx @@ -21,15 +21,19 @@ export default async function ClientPage() { ]); const ip = (await headers()).get("x-real-client-ip") ?? "0.0.0.0"; - const ticket = await issueSsoTicket(userId, hotelName, ip); - const onlineCount = await cached("online_count", 10_000, async () => { - const [row] = await db - .select({ total: count() }) - .from(User) - .where(eq(User.online, "1")); - return row?.total ?? 0; - }).catch(() => 0); + // Ticket write and online count run in parallel — the client page should + // render as fast as possible since the player is waiting for the game. + const [ticket, onlineCount] = await Promise.all([ + issueSsoTicket(userId, hotelName, ip), + cached("online_count", 10_000, async () => { + const [row] = await db + .select({ total: count() }) + .from(User) + .where(eq(User.online, "1")); + return row?.total ?? 0; + }).catch(() => 0), + ]); return (