From deac10e00aa229be5d337f2056a85d349bf7eb26 Mon Sep 17 00:00:00 2001 From: openhands Date: Thu, 9 Jul 2026 18:24:58 +0200 Subject: [PATCH] Add in-memory caching for online count, enable compression, and add staleTimes for router cache --- next.config.ts | 29 ++++++++++++++++++++++++----- src/app/api/online/count/route.ts | 8 ++++---- src/app/layout.tsx | 2 ++ src/components/site-header.tsx | 5 ++++- src/lib/cache.ts | 17 +++++++++++++++++ 5 files changed, 51 insertions(+), 10 deletions(-) create mode 100644 src/lib/cache.ts diff --git a/next.config.ts b/next.config.ts index 41aaadaa..246c56ca 100644 --- a/next.config.ts +++ b/next.config.ts @@ -29,20 +29,39 @@ const securityHeaders = [ ]; const nextConfig: NextConfig = { - // This app lives inside the Laravel repo tree (which has its own lockfiles); - // pin the Turbopack root so Next doesn't infer a parent directory. turbopack: { root: import.meta.dirname }, - - // Prisma + the MariaDB driver adapter are native/server-only — keep them out - // of the bundle (same approach as the habbo-next reference). serverExternalPackages: ["@prisma/adapter-mariadb", "mariadb", "@prisma/client"], + // Compress responses with gzip + compress: true, + + // Cache pages longer in the router cache for faster back/forward navigation + experimental: { + staleTimes: { + dynamic: 30, + static: 180, + }, + }, + + // Add caching headers for static assets async headers() { return [ { source: "/(.*)", headers: securityHeaders, }, + { + source: "/assets/(.*)", + headers: [ + { key: "Cache-Control", value: "public, max-age=31536000, immutable" }, + ], + }, + { + source: "/images/(.*)", + headers: [ + { key: "Cache-Control", value: "public, max-age=86400" }, + ], + }, ]; }, }; diff --git a/src/app/api/online/count/route.ts b/src/app/api/online/count/route.ts index 928e451c..15a701dc 100644 --- a/src/app/api/online/count/route.ts +++ b/src/app/api/online/count/route.ts @@ -4,16 +4,16 @@ // { count: 0 } (never 500) on DB failure. import { apiJson } from "@/lib/api"; +import { cached } from "@/lib/cache"; import { prisma } from "@/lib/prisma"; export const dynamic = "force-dynamic"; export async function GET(_req: Request) { try { - const count = await prisma.user.count({ - where: { online: "1" }, - }); - + const count = await cached("online_count", 10_000, () => + prisma.user.count({ where: { online: "1" } }), + ); return apiJson({ count }); } catch { return apiJson({ count: 0 }); diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 2494cc16..0b61cc72 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -67,6 +67,8 @@ export default async function RootLayout({ children }: { children: ReactNode })