perf: istemci istek cache'i (dedup+TTL) ve profil cache (Faz 5)
- lib/istek-cache: modül seviyesi in-flight dedup + 5dk TTL cache (SWR bağımlılığı olmadan); caller iptali paylaşılan fetch'i düşürmez - /api/facetler'in 5 çağrı yeri (hero, cta, kapı, sihirbaz adımları, demo) ve /api/katalog-ara cache'e bağlandı — sihirbazda 2↔3 adım geçişi ve tekrarlanan aramalar artık ağa çıkmıyor; /api/soru GET dedup-only (ttl 0) - katalog-arama: elle yukleniyor state'i kalktı, "cevaplanmamış sorgu" türetmesi + startTransition; rehber puanlaması Schwartzian; ⌘K listener'ı useEffectEvent ile tek sefer bağlanıyor - sihirbaz-adimlar: il sort/filter useMemo (çip başına 81 eleman kopyalanıp sıralanıyordu, harita dizisi referansı sabitlendi) - sohbet-client: stream chunk güncellemeleri startTransition'da — cevap akarken input yazımı bloklanmıyor - sihirbaz-profil: modül cache + event/storage geçersizlemesi (tek "+" tıklamasında 3 localStorage okuma + JSON.parse vardı) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { startTransition, useEffect, useState } from "react";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/navigation";
|
||||
import Image from "next/image";
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
} from "@/components/ui/chat-container";
|
||||
import { Message, MessageContent } from "@/components/ui/message";
|
||||
import { preloadMarkdown } from "@/components/ui/markdown-lazy";
|
||||
import { onbellekliJsonGetir } from "@/lib/istek-cache";
|
||||
import {
|
||||
PromptInput,
|
||||
PromptInputAction,
|
||||
@@ -101,8 +102,12 @@ export function SohbetClient({
|
||||
// Geçmiş sunucudan geldiyse (listem sayfası) ekstra tur atma;
|
||||
// popup gibi geç mount olan yerlerde eski davranış sürer.
|
||||
if (initialMesajlar != null) return;
|
||||
fetch("/api/soru")
|
||||
.then((res) => (res.ok ? res.json() : null))
|
||||
// ttlMs: 0 = yalnız in-flight dedup — /sonuc popup'ı ile /listem aynı anda
|
||||
// mount olursa tek istek; kredi/geçmiş POST sonrası değiştiği için
|
||||
// TTL cache'i bilinçli kapalı.
|
||||
onbellekliJsonGetir<{ mesajlar?: Mesaj[]; kredi?: number }>("/api/soru", {
|
||||
ttlMs: 0,
|
||||
})
|
||||
.then((data) => {
|
||||
if (data?.mesajlar) setMesajlar(data.mesajlar);
|
||||
if (typeof data?.kredi === "number") setKredi(data.kredi);
|
||||
@@ -164,8 +169,12 @@ export function SohbetClient({
|
||||
if (done) break;
|
||||
birikmis += decoder.decode(value, { stream: true });
|
||||
const anlik = birikmis;
|
||||
setMesajlar((m) =>
|
||||
m.map((x) => (x.id === asistanId ? { ...x, content: anlik } : x)),
|
||||
// Chunk başına gelen güncelleme acil değil: transition'a alınca
|
||||
// kullanıcı stream sürerken input'a takılmadan yazabilir
|
||||
startTransition(() =>
|
||||
setMesajlar((m) =>
|
||||
m.map((x) => (x.id === asistanId ? { ...x, content: anlik } : x)),
|
||||
),
|
||||
);
|
||||
}
|
||||
// Header'daki kredi pill'i layout'ta server-render edilir ve client
|
||||
|
||||
Reference in New Issue
Block a user