From 3ac7c7a5b3c8891fe55e5b5983559789cf132d0b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 1 Mar 2026 22:12:27 +0000 Subject: [PATCH] perf: lazy-load ShaderGradient and fix image cache TTL Co-authored-by: denshooter <44590296+denshooter@users.noreply.github.com> --- app/api/tech-stack/route.ts | 29 ++++++++++++++--------------- app/layout.tsx | 7 ++++++- next.config.ts | 32 ++++++++++++++++++++++++++++++-- 3 files changed, 50 insertions(+), 18 deletions(-) diff --git a/app/api/tech-stack/route.ts b/app/api/tech-stack/route.ts index 26d5a50..b9739dc 100644 --- a/app/api/tech-stack/route.ts +++ b/app/api/tech-stack/route.ts @@ -3,7 +3,8 @@ import { getTechStack } from '@/lib/directus'; import { checkRateLimit, getClientIp } from '@/lib/auth'; export const runtime = 'nodejs'; -export const dynamic = 'force-dynamic'; + +const CACHE_TTL = 300; // 5 minutes /** * GET /api/tech-stack @@ -28,26 +29,24 @@ export async function GET(request: NextRequest) { const techStack = await getTechStack(locale); if (techStack && techStack.length > 0) { - return NextResponse.json({ - techStack, - source: 'directus' - }); + return NextResponse.json( + { techStack, source: 'directus' }, + { headers: { 'Cache-Control': `public, s-maxage=${CACHE_TTL}, stale-while-revalidate=${CACHE_TTL * 2}` } } + ); } // Fallback: return empty (component will use hardcoded fallback) - return NextResponse.json({ - techStack: null, - source: 'fallback' - }); + return NextResponse.json( + { techStack: null, source: 'fallback' }, + { headers: { 'Cache-Control': `public, s-maxage=${CACHE_TTL}, stale-while-revalidate=${CACHE_TTL * 2}` } } + ); } catch (error) { - console.error('Error loading tech stack:', error); + if (process.env.NODE_ENV === 'development') { + console.error('Error loading tech stack:', error); + } return NextResponse.json( - { - techStack: null, - error: 'Failed to load tech stack', - source: 'error' - }, + { techStack: null, error: 'Failed to load tech stack', source: 'error' }, { status: 500 } ); } diff --git a/app/layout.tsx b/app/layout.tsx index a5433c1..2484918 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -2,10 +2,15 @@ import "./globals.css"; import { Metadata } from "next"; import { Inter, Playfair_Display } from "next/font/google"; import React from "react"; +import dynamic from "next/dynamic"; import ClientProviders from "./components/ClientProviders"; import { cookies } from "next/headers"; import { getBaseUrl } from "@/lib/seo"; -import ShaderGradientBackground from "./components/ShaderGradientBackground"; + +const ShaderGradientBackground = dynamic( + () => import("./components/ShaderGradientBackground"), + { ssr: false, loading: () => null } +); const inter = Inter({ variable: "--font-inter", diff --git a/next.config.ts b/next.config.ts index 4582d4d..218eb53 100644 --- a/next.config.ts +++ b/next.config.ts @@ -46,7 +46,7 @@ const nextConfig: NextConfig = { // Image optimization images: { formats: ["image/webp", "image/avif"], - minimumCacheTTL: 60, + minimumCacheTTL: 2592000, remotePatterns: [ { protocol: "https", @@ -169,7 +169,35 @@ const nextConfig: NextConfig = { ], }, { - source: "/api/(.*)", + // Only prevent caching for real-time/sensitive API routes + source: "/api/n8n/(.*)", + headers: [ + { + key: "Cache-Control", + value: "no-store, no-cache, must-revalidate, proxy-revalidate", + }, + ], + }, + { + source: "/api/auth/(.*)", + headers: [ + { + key: "Cache-Control", + value: "no-store, no-cache, must-revalidate, proxy-revalidate", + }, + ], + }, + { + source: "/api/email/(.*)", + headers: [ + { + key: "Cache-Control", + value: "no-store, no-cache, must-revalidate, proxy-revalidate", + }, + ], + }, + { + source: "/api/contacts/(.*)", headers: [ { key: "Cache-Control",