spinny:~/writing $ vim nextjs-16-cache-components.md
1~2Yıllardır Next.js'deki en sinir bozucu sorulardan biri şuydu: "Bu sayfa statik mi yoksa dinamik mi?". `cookies()`'a bir çağrı, farklı seçeneklere sahip bir `fetch`, bir veritabanı istemcisi, bir CMS, bir alışveriş sepeti veya bir parça özel içerik ekleyene kadar bu basit bir soru gibi görünüyor.3~4Next.js 16 ilginç çünkü bu konuşmayı daha az gizemli hale getirmeye çalışıyor. Karmaşıklığı ortadan kaldırmaz ancak zihinsel modeli değiştirir: rotalar varsayılan olarak dinamiktir, önbellek ihtiyaç duyulan yerde kendini bildirir ve `Suspense` taze kalan parçalarla hızlı kabuklar oluşturmanın doğal yolu haline gelir.5~6Anlaşılması gereken özellik Önbellek Bileşenleridir. Stable Turbopack, React Compiler, `proxy.ts` ve yeni geçersiz kılma API'leri önemlidir, ancak aynı sorun etrafında dönerler: çerçevenin perde arkasında neye karar verdiğini tahmin etmek zorunda kalmadan hızlı uygulamalar oluşturmak.7~8## Çünkü bu şey önemli9~10Gerçek bir uygulamada yalnızca "statik sayfalar" ve "dinamik sayfalar" yoktur. Farklı ihtiyaçlara sahip farklı parçalarınız var.11~12Ürün sayfası günde birkaç kez değişebilir. Fiyat daha sık değişebilir. Kullanılabilirlik neredeyse canlı olmalıdır. Kullanıcı adı kişiseldir. İncelemeler yayınlanabilir. Kenar çubuğu sabit olabilir. Araba öyle değil.13~14Her şeyi tek bir birim olarak ele alırsanız, her zaman iki uç noktadan biriyle karşılaşırsınız:15~16- agresif önbelleğe alma ve eski verileri görme riski;17- her yerde dinamik görüntü oluşturma ve performans gereğinden kötü.18~19Önbellek Bileşenleri tam olarak bu yanlış seçimi önlemeye hizmet eder.20~21## Uygulamadaki model22~23`cacheComponents: true` ile, `"use cache"` kullanarak neyin önbelleğe alınabileceğini bildirebilirsiniz. Daha sonra süreyi ve etiketleri `cacheLife()` ve `cacheTag()` ile ilişkilendirebilirsiniz. Dinamik parçalar dinamik kalır ve `Suspense` ile izole edilebilir.24~25```mermaid26flowchart TD27 Request[Kullanıcı isteği] --> Shell[Önbelleğe alınmış kabuk]28 Request --> Dynamic[Dinamik bölümler]29 Shell --> FirstPaint[İlk hızlı içerik]30 Dynamic --> Stream[Suspense'in içinden akış]31 Stream --> Complete[Tam sayfa]32```33~34Kurulum küçük:35~36```typescript37// next.config.ts38import type { NextConfig } from 'next';39~40const nextConfig: NextConfig = {41 cacheComponents: true,42};43~44export default nextConfig;45```46~47Büyük değişiklik yapılandırmada değil. Bileşenleri yazmaya nasıl başladığınızdır.48~49```tsx50// app/products/[slug]/page.tsx51import { Suspense } from 'react';52import { cacheLife, cacheTag } from 'next/cache';53~54async function getProduct(slug: string) {55 'use cache';56~57 cacheLife('hours');58 cacheTag(`product:${slug}`);59~60 return db.product.findUnique({ where: { slug } });61}62~63async function ProductDetails({ slug }: { slug: string }) {64 const product = await getProduct(slug);65~66 return (67 <section>68 <h1>{product.name}</h1>69 <p>{product.description}</p>70 </section>71 );72}73~74async function LiveInventory({ slug }: { slug: string }) {75 const inventory = await db.inventory.findFirst({ where: { slug } });76 return <p>{inventory.quantity} pezzi disponibili</p>;77}78~79export default async function ProductPage({ params }: { params: Promise<{ slug: string }> }) {80 const { slug } = await params;81~82 return (83 <>84 <ProductDetails slug={slug} />85 <Suspense fallback={<p>Controllo disponibilità...</p>}>86 <LiveInventory slug={slug} />87 </Suspense>88 </>89 );90}91```92~93Sayfanın tamamen önbelleğe alınmış veya tamamen dinamik olması gerekmez. Ürün sayfası hızlı ve tekrar kullanılabilir olabilir. Envanter taze kalabilir. Kullanıcı, en yavaş kısmı beklemeden bir şeyi hemen görür.94~95## `use cache` yürütülebilir belgedir96~97`"use cache"`'ın hoşuma giden yanı, sizi niyetinizi açıkça ortaya koymaya zorlaması. Bir fonksiyonu okuduğunuzda birisinin "bu veriler yeniden kullanılabilir" diye karar verdiğini hemen anlarsınız.98~99`fetch` kullanmadığınız zamanlarda özellikle kullanışlıdır. Birçok uygulama Prisma, Drizzle, dahili SDK'lar, CMS istemcileri veya hizmet işlevlerinden verileri okur. Bu durumlarda, yalnızca `fetch` seçeneklerine dayanan eski mantık yeterli değildi.100~101Temel bir kural:102~103- önbellek içeriği nispeten stabildir;104- ayrıntılı etiketler kullanın;105- dinamik izinleri, oturumları, alışveriş sepetlerini, bildirimleri ve işlem durumlarını bırakır;106- yavaş parçaları `Suspense` içine yerleştirin;107- "Performansı artırdık" demeden önce ölçün.108~109## Her şeyi atmadan geçersiz kılın110~111Önbellek yalnızca onu doğru bir şekilde güncelleyebiliyorsanız kullanışlıdır. Burada `cacheTag`, `revalidateTag` ve `updateTag` önem kazanıyor.112~113Örnek:114~115```typescript116'use server';117~118import { updateTag } from 'next/cache';119~120export async function updateProductName(productId: string, name: string) {121 await db.product.update({122 where: { id: productId },123 data: { name },124 });125~126 updateTag(`product:${productId}`);127}128```129~130Önemli detay etikettir. `product:${productId}` kesin bir sınır belirtir. `products` büyük bir kovayı anlatıyor. İlk başta devasa kova rahattır; Birkaç ay sonra, bir başlığı değiştirmek için uygulamanın yarısını geçersiz kılmanızın nedeni haline gelir.131~132## Stabil Turbopack: Her gün duyduğunuz kısım133~134Next.js 16, Turbopack'i geliştirme ve oluşturmanın merkezine getiriyor. Bu en şiirsel özellik değil ama çalışırken hissettiğiniz şey: daha erken başlayan sunucu, daha hızlı yenilenen, zorunlu bir kahve molası hissi vermeyen yapılar.135~136Bununla birlikte, özel eklentilerle dolu bir kod tabanını gözlerim kapalıyken taşımayacağım. Kontrol edeceğim:137~138- yerel yapı;139- standart dışı ithalat;140- MDX, SVG ve CSS;141- Web paketi eklentileri kaldı;142- kritik sayfalar;143- yapım sürelerindeki farklılıklar.144~145Yeni projeler için varsayılandan başlardım. Olgun olanlar için ölçülü bir göç yapardım.146~147## React Compiler: düşünceyi değil gürültüyü kaldırın148~149React Compiler 1.0 stabildir ve Next.js 16 bunu `reactCompiler` ile destekler. Söz verilen, manuel notlandırmanın çoğunu azaltmaktır: daha az `memo`, daha az `useMemo`, daha az `useCallback` "güvenlik için" kullanılır.150~151```typescript152// next.config.ts153import type { NextConfig } from 'next';154~155const nextConfig: NextConfig = {156 reactCompiler: true,157};158~159export default nextConfig;160```161~162Ona sihirli bir toz gibi davranmayacağım. Derleyici, kodun React kurallarına iyi uyması durumunda yardımcı olur. Bileşenlerin garip yan etkileri, gizli mutasyonları veya kötü kullanılmış kancaları varsa, öncelikle bunun düzeltilmesi gerekir.163~164Denemenin sağlıklı yolu:165~1661. güncelleme `eslint-plugin-react-hooks`;1672. gerçek ihlalleri düzeltmek;1683. kontrollü bir alanda etkinleştirin;1694. oluşturma süresini ve davranışını ölçün;1705. Manuel notlamayı yalnızca artık ihtiyaç duyulmadığında kaldırın.171~172Amaç her `useMemo`'yi silmek değil. Amacımız, render edilmekten korktuğumuz için önleyici not yazmayı bırakmaktır.173~174## `proxy.ts` ve ağ sınırı175~176Eski `middleware.ts`, `proxy.ts` olur. Bu bir isim değişikliğidir, ancak mantıklıdır: bu dosya istek sınırında yer alır, geleneksel arka uç tarzı genel ara yazılım değildir.177~178```typescript179// proxy.ts180import { NextRequest, NextResponse } from 'next/server';181~182export default function proxy(request: NextRequest) {183 const isLoggedIn = Boolean(request.cookies.get('session'));184~185 if (!isLoggedIn && request.nextUrl.pathname.startsWith('/dashboard')) {186 return NextResponse.redirect(new URL('/login', request.url));187 }188~189 return NextResponse.next();190}191```192~193Buradaki kural basit: küçük tutun. Yönlendirme, kimlik doğrulama yönlendirme, başlıklar, temel yeniden yazma işlemleri. İkinci bir arka uç gibi hissetmeye başlarsanız muhtemelen çok fazla şey yapıyordur.194~195## Gerçekten nasıl göç ederdim196~197Tüm özellikleri aynı anda açmayacağım. Bunu yapardım:198~1991. Sonraki, React ve React DOM'u güncelliyorum;2002. Resmi kod modunu başlatıyorum;2013. `params`, `searchParams`, `cookies()`, `headers()` ve `draftMode()` üzerinde bozulan değişiklikleri düzeltiyorum;2024. `middleware.ts`'ı `proxy.ts`'e taşıyorum;2035. Yapıları ve kritik sayfaları kontrol ediyorum;2046. Önbelleğin şu anda sürtünme yarattığı bir bölümde Önbellek Bileşenlerini etkinleştiriyorum;2057. Etiketler ve geçersiz kılma kurallarını ben tanımlarım;2068. React Compiler'ı ayrı ayrı denedim;2079. öncesi ve sonrası metriklerin karşılaştırılması.208~209İyi geçiş, tüm yeni özellikleri kullanan geçiş değildir. Uygulamanın davranışını daha okunabilir kılan şey budur.210~211## Düşünme biçiminde neler değişir?212~213Next.js 16'nın en faydalı yanı sizi niyetleri daha iyi adlandırmaya zorlamasıdır. Bir fonksiyon sadece "ürünü veri tabanından almak" değildir. "Ürünü alın, saatlerce önbelleğe alabilirim, bu etiketle geçersiz kılarım". Bir bileşen yalnızca "sayfayı oluşturmak" değildir. "Bu hızlı kabuk, bu parça kişisel, bu akışla geliyor."214~215İlk başta daha fazla iş varmış gibi görünüyor. Daha sonra bu bir tür sakinleşmeye dönüşür. Performans kararları artık varsayılanların, buluşsal yöntemlerin ve kabile hafızasının birleşiminde gizli değil. Kodun içindeler.216~217## Yararlı kaynaklar218~219- [Next.js 16 sürüm notları](https://nextjs.org/blog/next-16)220- [Önbellek Bileşenleri - Next.js belgeleri](https://nextjs.org/docs/app/getting-started/cache-components)221- [önbellek kullan - Next.js belgeleri](https://nextjs.org/docs/app/api-reference/directives/use-cache)222- [React Derleyici v1.0](https://react.dev/blog/2025/10/07/react-compiler-1)223~
NORMAL · nextjs-16-cache-components.md [readonly]223 lines · :q to close