Add in-memory caching for online count, enable compression, and add staleTimes for router cache
This commit is contained in:
1 parent
b058a3827b
commit
deac10e00a
5 files changed
+51
-10
No files matched your search
+24
-5
@@ -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" },
|
||||
],
|
||||
},
|
||||
];
|
||||
},
|
||||
};
|
||||
|
||||
@@ -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 });
|
||||
|
||||
@@ -67,6 +67,8 @@ export default async function RootLayout({ children }: { children: ReactNode })
|
||||
<head>
|
||||
<meta name="theme-default-dark" content={String(defaultDark)} />
|
||||
<script src="/scripts/theme-init.js" />
|
||||
<link rel="preconnect" href="https://www.habbo.com" />
|
||||
<link rel="dns-prefetch" href="https://www.habbo.com" />
|
||||
</head>
|
||||
<body
|
||||
className="flex min-h-screen flex-col site-bg"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import Link from "next/link";
|
||||
import { auth } from "@/lib/auth";
|
||||
import { cached } from "@/lib/cache";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { siteSettings } from "@/lib/services/site-settings";
|
||||
|
||||
@@ -15,7 +16,9 @@ export async function SiteHeader() {
|
||||
|
||||
let online = 0;
|
||||
try {
|
||||
online = await prisma.user.count({ where: { online: "1" } });
|
||||
online = await cached("online_count", 10_000, () =>
|
||||
prisma.user.count({ where: { online: "1" } }),
|
||||
);
|
||||
} catch {
|
||||
online = 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
type CacheEntry<T> = { data: T; expiresAt: number };
|
||||
const store = new Map<string, CacheEntry<unknown>>();
|
||||
|
||||
export function cached<T>(key: string, ttlMs: number, fn: () => Promise<T>): Promise<T> {
|
||||
const existing = store.get(key);
|
||||
if (existing && existing.expiresAt > Date.now()) {
|
||||
return Promise.resolve(existing.data as T);
|
||||
}
|
||||
return fn().then((data) => {
|
||||
store.set(key, { data, expiresAt: Date.now() + ttlMs });
|
||||
return data;
|
||||
});
|
||||
}
|
||||
|
||||
export function bustCache(key: string): void {
|
||||
store.delete(key);
|
||||
}
|
||||
Reference in new issue
Block a user