perf: cache scoped site settings
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled

This commit is contained in:
Your Name 2026-04-30 01:43:41 +08:00
parent 3249b19f56
commit b630267f33

View File

@ -463,7 +463,22 @@ const PUBLIC_SITE_SETTINGS_SCOPES = new Set<string>([
"home",
]);
function createScopedSiteSettingsResponse(data: Record<string, unknown>) {
const SCOPED_SITE_SETTINGS_SERVER_CACHE_TTL_MS = 30_000;
const scopedSiteSettingsServerCache = new Map<
PublicSiteSettingsScope,
{ data: Record<string, unknown>; expiresAt: number }
>();
function createScopedSiteSettingsResponse(
scope: PublicSiteSettingsScope,
data: Record<string, unknown>,
cacheStatus: "HIT" | "MISS" = "MISS"
) {
scopedSiteSettingsServerCache.set(scope, {
data,
expiresAt: Date.now() + SCOPED_SITE_SETTINGS_SERVER_CACHE_TTL_MS,
});
const response = NextResponse.json(data);
// Lightweight public settings change rarely; keep them browser-local briefly
// so page opens do not repeatedly wait on the large full settings endpoint.
@ -471,6 +486,8 @@ function createScopedSiteSettingsResponse(data: Record<string, unknown>) {
"Cache-Control",
"private, max-age=30, stale-while-revalidate=120"
);
response.headers.set("X-Site-Settings-Scope", scope);
response.headers.set("X-Site-Settings-Cache", cacheStatus);
return response;
}
@ -509,7 +526,7 @@ async function getScopedPublicSiteSettings(scope: PublicSiteSettingsScope) {
const { settings, valueByKey } = await readScopedSiteSettings([
"login_notification",
]);
return createScopedSiteSettingsResponse({
return createScopedSiteSettingsResponse(scope, {
...createBrandingSettings(settings as Record<string, unknown> | undefined),
notification: valueByKey.get("login_notification") || {
enabled: false,
@ -523,7 +540,7 @@ async function getScopedPublicSiteSettings(scope: PublicSiteSettingsScope) {
const { valueByKey } = await readScopedSiteSettings([
AGENT_WORKFLOW_BRAND_MODEL_CONFIG_KEY,
]);
return createScopedSiteSettingsResponse({
return createScopedSiteSettingsResponse(scope, {
agentWorkflowBrandModelConfig: normalizeAgentWorkflowBrandModelConfig(
valueByKey.get(AGENT_WORKFLOW_BRAND_MODEL_CONFIG_KEY)
),
@ -535,7 +552,7 @@ async function getScopedPublicSiteSettings(scope: PublicSiteSettingsScope) {
AGENT_PRESET_LIBRARY_CONFIG_KEY,
AGENT_WORKFLOW_SHOWCASE_CONFIG_KEY,
]);
return createScopedSiteSettingsResponse({
return createScopedSiteSettingsResponse(scope, {
agentPresetLibraryConfig: normalizeAgentPresetLibraryConfig(
valueByKey.get(AGENT_PRESET_LIBRARY_CONFIG_KEY)
),
@ -571,7 +588,7 @@ async function getScopedPublicSiteSettings(scope: PublicSiteSettingsScope) {
valueByKey.get(AGENT_PSD_TEMPLATE_CATEGORY_TAG_CONFIG_KEY)
);
return createScopedSiteSettingsResponse({
return createScopedSiteSettingsResponse(scope, {
...createBrandingSettings(typedSettings),
agentEnabled: typedSettings?.agentEnabled ?? true,
canvasAgentModeEnabled: normalizeCanvasAgentModeEnabled(
@ -615,6 +632,7 @@ async function getScopedPublicSiteSettings(scope: PublicSiteSettingsScope) {
if (scope === "branding") {
const { settings } = await readScopedSiteSettings([]);
return createScopedSiteSettingsResponse(
scope,
createBrandingSettings(settings as Record<string, unknown> | undefined)
);
}
@ -622,7 +640,7 @@ async function getScopedPublicSiteSettings(scope: PublicSiteSettingsScope) {
if (scope === "chat") {
const { settings } = await readScopedSiteSettings([]);
const typedSettings = settings as Record<string, unknown> | undefined;
return createScopedSiteSettingsResponse({
return createScopedSiteSettingsResponse(scope, {
...createBrandingSettings(typedSettings),
showAutoModel: typedSettings?.showAutoModel ?? true,
usageTimeEnabled: typedSettings?.usageTimeEnabled ?? false,
@ -648,7 +666,7 @@ async function getScopedPublicSiteSettings(scope: PublicSiteSettingsScope) {
valueByKey.get(VIDEO_CANVAS_SIDEBAR_ENABLED_KEY)
);
return createScopedSiteSettingsResponse({
return createScopedSiteSettingsResponse(scope, {
...createBrandingSettings(typedSettings),
agentEnabled: typedSettings?.agentEnabled ?? true,
canvasAgentModeEnabled: normalizeCanvasAgentModeEnabled(
@ -685,7 +703,7 @@ async function getScopedPublicSiteSettings(scope: PublicSiteSettingsScope) {
]);
const typedSettings = settings as Record<string, unknown> | undefined;
return createScopedSiteSettingsResponse({
return createScopedSiteSettingsResponse(scope, {
...createBrandingSettings(typedSettings),
bannerEnabled: typedSettings?.bannerEnabled ?? true,
bannerText:
@ -726,7 +744,7 @@ async function getScopedPublicSiteSettings(scope: PublicSiteSettingsScope) {
]);
const typedSettings = settings as Record<string, unknown> | undefined;
return createScopedSiteSettingsResponse({
return createScopedSiteSettingsResponse(scope, {
...createBrandingSettings(typedSettings),
canvasDefaultModelId: typedSettings?.canvasDefaultModelId || null,
lovartComposerPrefix: normalizeLovartComposerPrefix(
@ -769,7 +787,13 @@ export async function GET(request: NextRequest) {
try {
const scope = request.nextUrl.searchParams.get("scope") || "";
if (PUBLIC_SITE_SETTINGS_SCOPES.has(scope)) {
return getScopedPublicSiteSettings(scope as PublicSiteSettingsScope);
const scopedScope = scope as PublicSiteSettingsScope;
const cached = scopedSiteSettingsServerCache.get(scopedScope);
if (cached && cached.expiresAt > Date.now()) {
return createScopedSiteSettingsResponse(scopedScope, cached.data, "HIT");
}
return getScopedPublicSiteSettings(scopedScope);
}
const session = await auth().catch(() => null);