Tarayıcının eline gelen HTML'i birisi üretti. Soru şu: ne zaman üretti?
Cevap kabaca şu dördünden biri. Build ederken. Kullanıcı isterken. Daha önce üretilmişti, arka planda tazelendi. Ya da hiç üretilmedi, tarayıcı kendisi çizdi.
Modern Next.js'te bu bir "strateji seçme" meselesinden çok, her parça içeriğe "bu ne zaman üretilmeli?" diye sormaya dönüşüyor. Aşağıda beş yaklaşımı sırayla açıyorum.
CSR (Client-Side Rendering)
App Router'da "use client" yazmak bir component'i doğrudan CSR yapmaz. Component yine ilk request'te server'da render edilip HTML'e dahil olabilir. Server render'ını gerçekten kapatıp render'ı client'a taşımak istiyorsan ssr: false ile dinamik import kullanırsın.
CSR; window / document kullanan, browser'a özel çalışan veya SEO'nun önemli olmadığı interaktif ekranlarda mantıklı. Ama SEO ve hızlı ilk render önemliyse her şeyi CSR'a bırakmak genelde iyi bir tercih değil: tarayıcı önce boş bir kabuk alır, JS'i indirip çalıştırır, veriyi ayrı bir istekle çeker ve içerik ancak ondan sonra çizilir.

SSG (Static Site Generation)
Sayfa build time'da generate edilir. Veri build sırasında fetch edilir ve elde edilen HTML statik olarak oluşturulup CDN'e deploy edilir. Kullanıcı request attığında server tarafında tekrar data fetch edilmez; CDN hazır HTML'i direkt döner.
Bu yüzden TTFB (Time to First Byte) request anındaki data fetch süresinden etkilenmez.
Dezavantajı, içerik güncellendiğinde yeniden build/deploy gerekmesi ve çok büyük dataset'lerde build süresinin ciddi şekilde uzayabilmesidir.

ISR (Incremental Static Regeneration)
ISR, statik sayfaların belirli koşullarda yeniden generate edilmesini sağlayarak SSG ile SSR arasında bir yaklaşım sunar. Sayfa build time'da generate edilir ve revalidate ile cache süresi belirlenir.
revalidate: 60, her 60 saniyede bir yenile demek değildir. Süre dolduktan sonra gelen ilk request mevcut HTML'i alır ve arka planda yeni sayfa generate edilir. Sonraki request yeni içeriği alır.
Yani ISR request-driven regeneration kullanır; trafik yoksa regeneration da yoktur.
revalidateTag ile süreyi beklemeden cache invalidation tetiklenebilir.
Dezavantajı: stok, canlı fiyat veya kalan koltuk gibi anlık doğruluk gerektiren verilerde bir kullanıcının stale data görmesi kabul edilemez.

SSR (Server-Side Rendering)
Kullanıcı sayfayı istediğinde Next.js gerekli verileri server'da fetch eder, HTML'i üretir ve response olarak gönderir.
Next.js App Router'da SSR özellikle request'e bağlı veya güncel olması gereken veriler için önemlidir. cookies(), headers(), searchParams veya cache'lenmemiş data fetch gibi dinamik API'ler kullanıldığında route dynamic render edilir.
Bunun karşılığında her request'te server-side işlem yapıldığı için TTFB, data source'un latency'sinden etkilenir. Yani SSR güncel ve kişiselleştirilmiş içerik sağlar ama bunun maliyeti request başına server-side rendering'dir.

PPR (Partial Prerendering)
PPR, sayfanın statik ve dinamik bölümlerini aynı response içinde birleştiren bir rendering yaklaşımıdır.
Build sırasında statik kabuk hazırlanır, dinamik bölümler için placeholder bırakılır. Kullanıcı request attığında kabuk hemen gönderilir; dinamik parçalar server'da hazırlandıkça aynı response içinde doldurulur.
Önceki stratejilerde sayfa genel olarak statik ya da dinamik kabul ediliyordu. PPR ile sayfanın sadece gerçekten dinamik olan kısmını request time'da render edebilirsin.
Next.js 16'da cacheComponents: true ile model daha da değişiyor: cache'lenecek içerikleri use cache ile açıkça işaretliyorsun.
Dikkat: dinamik içerik bir Suspense sınırıyla ayrılmazsa tüm shell'i bloke edebilir. Ayrıca fallback tasarımı önemlidir; kullanıcı önce fallback'i, ardından gerçek içeriği görür.

TL;DR
Pratikte artık sorulacak soru "hangi rendering stratejisini kullanmalıyım?" değil. Önce içeriğin kendisine bakmak gerekiyor:
- Bu içerik kullanıcıya özel mi?
- Ne sıklıkla değişiyor ve birinin eski hâlini görmesi kabul edilebilir mi?
- Daha da önemlisi, bu dinamik parçanın sayfanın geri kalanını bekletmesine gerçekten gerek var mı?
Bu soruların cevapları; içeriğin build time'da mı hazırlanacağını, cache'lenip ne zaman yenileneceğini veya her request'te mi render edileceğini belirliyor. Modern Next.js rendering yaklaşımında amaç tek bir strateji seçmek değil, her içeriği ihtiyacına göre doğru zamanda render etmek.
