diff --git a/next.config.ts b/next.config.ts
index b875547..eab2aae 100644
--- a/next.config.ts
+++ b/next.config.ts
@@ -22,12 +22,13 @@ const nextConfig: NextConfig = {
"openai",
"resend",
],
- ...(kaynakKisitli
- ? {
- // cacheComponents açıkken prerender fazında source map üretimi varsayılan
- // açık; 1900+ statik sayfada ciddi bellek maliyeti var.
- enablePrerenderSourceMaps: false,
- experimental: {
+ experimental: {
+ // radix-ui kök barrel'ı 36 alt paketi çeker ve Next'in varsayılan
+ // optimize listesinde yoktur; named import'lar doğrudan alt modüle
+ // çevrilir (dev boot / build modül grafiği küçülür).
+ optimizePackageImports: ["radix-ui"],
+ ...(kaynakKisitli
+ ? {
// Turbopack'ın Rust tarafı NODE_OPTIONS heap sınırını görmez; bellek
// hedefi byte cinsinden ayrıca verilir (1.5 GB).
turbopackMemoryLimit: 1_610_612_736,
@@ -35,7 +36,14 @@ const nextConfig: NextConfig = {
// worker × 4 sayfa. Her worker ayrı bir Node süreci/heap'idir.
cpus: 1,
staticGenerationMaxConcurrency: 4,
- },
+ }
+ : {}),
+ },
+ ...(kaynakKisitli
+ ? {
+ // cacheComponents açıkken prerender fazında source map üretimi varsayılan
+ // açık; 1900+ statik sayfada ciddi bellek maliyeti var.
+ enablePrerenderSourceMaps: false,
}
: {}),
async redirects() {
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index 97fcb66..6303e82 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -10,7 +10,7 @@ import { KaydetBannerLazy } from "@/features/liste/components/kaydet-banner-lazy
import { TercihProfiliKapisiLazy } from "@/features/liste/components/tercih-profili-kapisi-lazy";
import { HeaderGate } from "@/components/header-gate";
import { ProgressiveBlur } from "@/components/ui/skiper-ui/skiper41";
-import { DevPanel } from "@/components/dev/dev-panel";
+import { DevPanelMount } from "@/components/dev/dev-panel-mount";
import { ScrollFlow } from "@/components/scroll-flow";
import { JsonLd, organizationJsonLd, webSiteJsonLd, SITE_URL } from "@/lib/seo";
import "./globals.css";
@@ -85,19 +85,6 @@ export default function RootLayout({
// içerikle büyümeli, viewport tabanı body'deki min-h-dvh'den gelir.
className={`${calSans.variable} ${clarityCity.variable} ${geistMono.variable} ${bricolage.variable} antialiased`}
>
- {/* Rybbit analitik — beforeInteractive her zaman
içine defer olarak
- enjekte edilir. Yalnızca prod build'de: Rybbit localhost'u da takip
- ettiği için dev trafiği prod verisini kirletmesin (DevPanel ile aynı
- kapı). mask-patterns: /sonuc URL'i ham başarı sıralamasını,
- /odeme/sonuc sipariş kimliğini taşıyor — path tek satırda toplanır. */}
- {process.env.NODE_ENV === "production" ? (
-
- ) : null}
{/* Site geneli progressive blur — üst ve alt */}
@@ -130,10 +117,23 @@ export default function RootLayout({
{/* İlk "+" için sıra + sihirbaz kapısı */}
- {/* Dev süperadmin paneli — prod build'de hiç render edilmez */}
- {process.env.NODE_ENV !== "production" ? : null}
+ {/* Dev süperadmin paneli — prod build'de modül grafiğine bile girmez */}
+ {process.env.NODE_ENV !== "production" ? : null}
+ {/* Rybbit analitik — afterInteractive: hydration sonrası client'ta
+ enjekte edilir, LCP/kritik yolla yarışmaz. Yalnızca prod build'de:
+ Rybbit localhost'u da takip ettiği için dev trafiği prod verisini
+ kirletmesin (DevPanel ile aynı kapı). mask-patterns: /sonuc URL'i
+ ham başarı sıralamasını, /odeme/sonuc sipariş kimliğini taşıyor. */}
+ {process.env.NODE_ENV === "production" ? (
+
+ ) : null}
);
diff --git a/src/components/dev/dev-panel-mount.tsx b/src/components/dev/dev-panel-mount.tsx
new file mode 100644
index 0000000..be5d328
--- /dev/null
+++ b/src/components/dev/dev-panel-mount.tsx
@@ -0,0 +1,18 @@
+"use client";
+
+import dynamic from "next/dynamic";
+
+// NODE_ENV build sırasında statik yerine konur: prod build'de import()
+// erişilemez dalda kalır ve dev-panel (+ dev server-action proxy'leri)
+// modül grafiğine hiç girmez — layout'taki statik import ~92 KB'lık
+// paylaşılan chunk'a dev kodu taşıyordu. Dev'de panel dynamic yüklenir.
+const DevPanelIc =
+ process.env.NODE_ENV !== "production"
+ ? dynamic(() => import("./dev-panel").then((m) => m.DevPanel), {
+ ssr: false,
+ })
+ : null;
+
+export function DevPanelMount() {
+ return DevPanelIc ? : null;
+}
diff --git a/src/components/use-pixel-heat.ts b/src/components/use-pixel-heat.ts
index ee020d8..8c59ef6 100644
--- a/src/components/use-pixel-heat.ts
+++ b/src/components/use-pixel-heat.ts
@@ -16,7 +16,11 @@
*/
import { useEffect, type RefObject } from "react";
-import { animate, type AnimationPlaybackControls } from "motion";
+// WAAPI tabanlı mini animate yeterli (yalnızca duration/ease kullanılıyor);
+// tam motor client bundle'ına girmez. Tip mini'den export edilmiyor —
+// type-only import build'de silinir, maliyeti yok.
+import { animate } from "motion/mini";
+import type { AnimationPlaybackControls } from "motion";
const FINE_POINTER_QUERY = "(hover: hover) and (pointer: fine)";
const HOT_COLOR = "#f97316"; // orange-500
diff --git a/src/features/sihirbaz/components/sihirbaz-cagri-karti.tsx b/src/features/sihirbaz/components/sihirbaz-cagri-karti.tsx
index 4a4412b..2568f83 100644
--- a/src/features/sihirbaz/components/sihirbaz-cagri-karti.tsx
+++ b/src/features/sihirbaz/components/sihirbaz-cagri-karti.tsx
@@ -4,7 +4,7 @@ import { useEffect, useRef, useState, useSyncExternalStore } from "react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { ArrowRight } from "lucide-react";
-import { animate } from "motion";
+import { animate } from "motion/mini";
import { useReducedMotion } from "motion/react";
import { Button } from "@/components/ui/button";
import { PixelField } from "@/components/pixel-decor";