İçeriğe geç
YAZILIM

Next.js 15 ile kurumsal sitede sunucu bileşenleri

Hangi bileşen sunucuda kalmalı, hangisi istemciye taşınmalı?

Kerem Aksoy
Kurucu Ortak · Yazılım Mimarisi
28 MAY 2026 · 11 DK OKUMA

Varsayılan sunucudur

App Router’da bileşen sunucuda kalır; istemciye taşımak bir karardır, tersi değil. Kurumsal sitede bu karar yanlış verilince mega menü, sepet çekmecesi ve tema anahtarı tüm sayfayı hidrate eder. JS kilogramı artar, INP düşer, “neden yavaş?” toplantısı başlar.

Sunucuda kalması gerekenler: vitrin listeleri, fiyat, SEO metni, sepet adedi, kullanıcı adı. İstemciye taşınanlar: hover menü, drawer, tema, form etkileşimi, sepet adet düğmesi. Sınır, “tıklanınca değişen küçük ada”dır; ada büyüdükçe sayfa istemci uygulamasına döner.

Sınır çizgisi

use client dosyası çocuklarını da istemci yapmaz ama o dosyanın kendisi pakete girer. Bu yüzden istemci sınırını mümkün olduğunca yaprakta tutun. Bir sunucu sayfası, küçük bir CartButton istemci bileşeni import eder; tüm header’ı istemci ilan etmez.

Veri çekme sunucuda kalsın. İstemci useEffect ile aynı REST’i tekrar çağırıyorsa RSC’nin anlamı kalmamıştır. Çerez sepeti sunucu action ile güncellenir, router.refresh() adedi yeniler. Bu model, Faz 3’te kurduğumuz mağaza akışının da omurgasıdır.

  • Sunucu: okuma, meta, JSON-LD, fiyat.
  • İstemci: etkileşim, geçici UI durumu.
  • Action: yazma (sepet, form, yorum).
  • Yenileme: refresh, etiket, path — seçici.

Gizli maliyetler

Büyük Date formatları, markdown işleme ve görsel dönüştürme sunucuda yapılır. Bunları istemciye vermek, hidrasyonu şişirir. Tiptap editörü yalnızca admin’de istemcidir; vitrin yazısı statik JSON’dan HTML üretir. Ziyaretçi editör indirmez.

Üçüncü parti sohbet betiği layout’a konursa tüm uygulama onun zamanına bağlanır. Dinamik import ve afterInteractive bile bazen geç kalır; etkileşim veya zaman eşiği daha dürüst bir sözleşmedir.

Sunucu action’ları formun kaynağıdır. Zod aynı şemayı istemci ve sunucuda paylaşır; “önce client doğrula, sunucu güvensin” modeli kırılır. Action içinde cookies() ve headers() okumak bileşeni dinamik yapar — vitrin listesini bu yüzden action’dan ayırın. Statik sayfa, dinamik ada: sepet rozeti layout’ta dinamik kalır, yazı gövdesi statik üretilir.

Hata sınırları (error boundary) istemci ağaçlarında anlamlıdır. Sunucu hata sayfası error.tsx ile ayrılır; ikisini karıştırmayın. Bir istemci ada düştüğünde tüm sayfayı kırmızıya boyamayın. Logging’i action içinde console.log ile değil, yapısal kayıtla yapın — production’da log yoksa gece izi de yok.

Paket analizini çeyreklik bakın. “Sadece bir chart” diye eklenen recharts, vitrine sızarsa LCP değil INP şişer. Admin’e özel kütüphaneler app/(admin) sınırında kalsın. Shared components/ui ise her iki tarafa da gider; içine sohbet SDK’sı koymayın.

Sonuç

Next.js 15’te performans, sunucu varsayılanını koruma disiplinidir. İstemciye taşıdığınız her satır için “bu tıklama mı, yoksa vitrin mi?” diye sorun. Cevap vitrinse geri alın. Kurumsal site bir gösteri uygulaması değil, hızlı bir belgedir; etkileşim adaları belgenin üstüne serilir.

Yayın öncesi kontrol

Bundle analizinde vitrine sızan admin kütüphanesi, sohbet SDK’sı veya chart var mı bakın. Varsa sınır yanlış çizilmiştir. Header’ın tamamı use client ise sepet adedi için bütün navigasyonu hidrate ediyorsunuz demektir. Yaprak bileşene indirin, ölçün, sonra tartışın.

Dinamik cookies() okuyan bir layout, altındaki statik yazıları da dinamik yapabilir. Yazı gövdesini layout’tan ayırın; rozeti küçük bir dinamik ada yapın. Bu ayrım, ISR’nin anlamını korur. Korunmazsa her yorumda tüm blog soğur.

Sunucu eylemini formun yanında startTransition ile sarmalayınca yönlendirme yarışır. Yönlendiren eylemleri useActionState ile bağlayın. Bu kuralı ihlal eden PR, “ara sıra çift sipariş” üretir. Çift sipariş, performans değil güven meselesidir.

İstemci sınırı “etkileşim var” değil, “tarayıcı API’si şart” olsun. Tema düğmesi istemcidir; fiyat listesi değildir. Bu cümleyi kod incelemesinde tekrar edin. Tekrar etmezseniz altı ay sonra her kart use client ile açılır.

  • Vitrin paketinde admin veya sohbet SDK’sı var mı?
  • Layout cookies() okuyor mu, yazı ISR mı?
  • Yönlendiren eylem useActionState ile mi bağlı?
  • Yeni istemci sınırı gerekçeli mi?

Sahada tekrar edenler

Sunucu bileşeninde new Date() ile “şu an” yazmak, sayfayı kişiselleştirmez; önbelleği bozar. Saat gösteriyorsanız istemci adası yeter. Bozulan önbellek, TTFB’yi üçüncü parti betikten daha sinsi düşürür çünkü kimse “tarih yüzünden” demez.

Streaming’i kahraman sanmayın. Şablon yavaşsa iskelet üç saniye güler, kullanıcı gider. Önce veri suyunu kısın, sonra stream edin. Aksini yapan ekipler “Suspense koyduk” diye kutlar, CrUX aynı kalır.

Bu yazıyı paylaş
Kerem Aksoy
Kurucu Ortak · Yazılım Mimarisi · Vexria

Kurumsal portallar ve ERP entegrasyonlarında on yılı aşkın deneyim. Vexria'da teknik vizyon, kod kalitesi ve teslim edilebilir mimariden sorumlu.

İlgili yazılar

Yorumlar 0

Yorum yazın
Teklif AlWA