React Server Components vs Client-side React (SPA) Karşılaştırması

Sunucuda önceden render edilen, sıfır-JS-varsayılan React katmanı

VS
Client-side React (SPA)

Tarayıcıda render edilen, klasik ve olgun React kullanım biçimi

18 dk okumaFrontend

Hızlı Karar

İçerik-ağır, SEO-kritik yüzeylerde RSC ölçülebilir kazanç veriyor: react.dev'in örneğinde 75K gzip'lik kütüphane client'a hiç gitmiyor. Yoğun-interaktif iç panellerde (dashboard, admin) client-first hem daha basit hem daha az hata yüzeyi sunuyor. Kritik uyarı gerçek: Server'dan Client'a tam obje prop'u geçmek objenin tüm alanlarını flight payload'a yazdırır; sınırı yanlış çizersen kazanç sessizce erir. Kararı ölçümle ver, moda ile değil.

React Server ComponentsClient-side React (SPA)
Tam sonucu oku

Puan Karşılaştırması

Grafik yükleniyor...

Detaylı Puanlama

Detaylı Puanlama: React Server Components ve Client-side React (SPA) — kategori bazında 10 üzerinden puanlar
KategoriReact Server ComponentsClient-side React (SPA)
Performans
8/10
6/10
Öğrenme Kolaylığı
4/10
8/10
Ekosistem
7/10
9/10
Topluluk
7/10
9/10
İş Pazarı
7/10
8/10
Gelecek
9/10
7/10

Artıları & Eksileri

React Server Components

Artıları

  • İçerik-ağır sayfalarda ağır kütüphaneleri (markdown parser, sanitizer) client bundle'a hiç sokmaz — react.dev'in kendi örneğinde 75K gzip tasarruf
  • Sunucu tarafında veri çekme, client-server waterfall'ını (ör. Note→Author sıralı fetch) ortadan kaldırır
  • İlk yükte HTML anında görünür, JS hydration'ı beklemeden içerik okunabilir
  • Next.js App Router ile ISR/cache katmanına doğal entegre — stale-while-revalidate ile anında servis
  • React 19.2 Activity + Next.js 16.3 Instant Navigations ile SPA-hissi kaybı büyük ölçüde kapatılıyor
  • Turbopack'in chunk-group birleştirmesi client bundle'ı otomatik optimize ediyor

Eksileri

  • Server→Client sınırından geçen her prop serileştirilmeli; desteklenmeyen bir değer geçirilirse React exception fırlatır
  • 'use client' bir dosyayı işaretlediğinde o dosyanın TÜM transitive import'ları client bundle'a dahil olur — sınırı yanlış çizmek kazancı sessizce yok eder
  • Server Component context oluşturamaz, useState/useEffect gibi interaktif API kullanamaz
  • RSC'nin alttaki API'leri React minörleri arasında semver izlemiyor — bundler/framework spesifik sürüme pinlenmeli
  • 3 Aralık 2025'te kritik unauthenticated RCE açığı bulundu (19.0.1/19.1.2/19.2.1 ile yamalandı) — framework'e bağımlı güvenlik yüzeyi büyüyor
  • Öğrenme eğrisi dik: sunucu/client sınırını doğru yerde çizmek deneyim gerektirir, hata mesajları çoğu zaman çalışma zamanında ortaya çıkar

En Uygun

İçerik-ağır, SEO-kritik sayfalar (blog, ürün, dokümantasyon, karşılaştırma sayfaları)Veri kaynağına yakın, sunucuda tek seferde çekilebilen ilk-yük ağırlıklı ekranlarISR/cache ile beslenen, sık değişmeyen ama trafiği yüksek sayfalarNext.js App Router'a zaten bağlı, framework-native mimari isteyen ekiplerClient JS bundle boyutunu ölçülebilir şekilde küçültmesi gereken projeler

Client-side React (SPA)

Artıları

  • Basit mental model: her component her zaman interaktif olabilir, sunucu/client sınırı düşünmeye gerek yok
  • Vite tabanlı tooling ile hızlı dev-server, HMR ve olgun code-splitting (Rollup)
  • Serileştirme sınırı yok — state doğrudan JS objesi olarak tarayıcıda yaşar, 'flight payload' tuzağı yok
  • En büyük ve en eski React ekosistemi; kütüphane, Stack Overflow cevabı ve işe alım havuzu en geniş
  • Sunucu koşturma zorunluluğu yok — statik hosting/CDN'e deploy edilebilir
  • Debugging tek ortamda (tarayıcı DevTools) yapılır, server/client ikili hata yüzeyi yok

Eksileri

  • İlk yük genelde boş `<div id="root">` + JS bundle — TTI ile FCP birbirine yakınsar, JS çalışmadan içerik görünmez
  • Ağır kütüphaneler (markdown parser, sanitizer, chart lib) her zaman client bundle'a girer, sunucuda bırakma seçeneği yok
  • Veri çekme sıralı `useEffect` zincirlerine kayarsa client-server waterfall riski yüksek
  • Tek chunk / sayfa-başı chunk stratejileri paylaşılan kodu tekrar tekrar indirtebilir — Turbopack'in çözmeye çalıştığı problem SPA tarafında tooling'e (Vite/Rollup) kalıyor
  • SEO ve ilk-yük performansı için ayrıca SSG/prerender katmanı kurmak gerekir, framework'ün kendisi bunu vermez

En Uygun

Yoğun-interaktif iç paneller (admin, dashboard) — sık state değişimi, sürükle-bırak, canlı filtrelemeKimlik doğrulamalı, SEO'nun öncelik olmadığı uygulamalarKüçük ekiplerin hızlı prototipleme ve MVP geliştirmesiStatik hosting/CDN'e deploy edilecek, sunucu koşturma maliyeti istenmeyen projelerMevcut büyük SPA codebase'lerin bakımı ve kademeli modernizasyonu

Kod Karşılaştırması

React Server Components
// Next.js App Router — Server Component (varsayılan)
// app/posts/[slug]/page.tsx
import { db } from '@/lib/db';
import LikeButton from './like-button'; // Client Component (ayrı dosyada 'use client')

interface PageProps {
  params: Promise<{ slug: string }>;
}

export default async function PostPage({ params }: PageProps) {
  const { slug } = await params;

  // Server tarafında doğrudan await — client-server waterfall yok,
  // marked/sanitize-html gibi ağır kütüphaneler client bundle'a hiç girmiyor
  const post = await db.post.findUnique({ where: { slug } });
  if (!post) return <div>Bulunamadı</div>;

  return (
    <article>
      <h1>{post.title}</h1>
      {/* Yalnızca serileştirilebilir prop'lar Client Component'e geçer */}
      <div dangerouslySetInnerHTML={{ __html: post.renderedHtml }} />
      <LikeButton postId={post.id} initialCount={post.likeCount} />
    </article>
  );
}

// app/posts/[slug]/like-button.tsx
'use client';
import { useState, useTransition } from 'react';

export default function LikeButton({ postId, initialCount }: { postId: string; initialCount: number }) {
  const [count, setCount] = useState(initialCount);
  const [isPending, startTransition] = useTransition();

  return (
    <button
      disabled={isPending}
      onClick={() => startTransition(async () => {
        setCount((c) => c + 1);
        await fetch(`/api/posts/${postId}/like`, { method: 'POST' });
      })}
    >
      Beğen ({count})
    </button>
  );
}
Client-side React (SPA)
// Vite + React — Client-side SPA
// src/pages/PostPage.tsx
import { useEffect, useState } from 'react';
import { useParams } from 'react-router';

interface Post {
  id: string;
  title: string;
  renderedHtml: string;
  likeCount: number;
}

export default function PostPage() {
  const { slug } = useParams();
  const [post, setPost] = useState<Post | null>(null);
  const [isLiking, setIsLiking] = useState(false);

  useEffect(() => {
    // Tüm veri çekme client'ta — waterfall riski burada başlar
    let cancelled = false;
    fetch(`/api/posts/${slug}`)
      .then((res) => res.json())
      .then((data) => { if (!cancelled) setPost(data); });
    return () => { cancelled = true; };
  }, [slug]);

  if (!post) return <div>Yükleniyor...</div>; // JS çalışmadan bu ekran hiç görünmez

  async function handleLike() {
    setIsLiking(true);
    setPost((p) => (p ? { ...p, likeCount: p.likeCount + 1 } : p));
    await fetch(`/api/posts/${post!.id}/like`, { method: 'POST' });
    setIsLiking(false);
  }

  return (
    <article>
      <h1>{post.title}</h1>
      <div dangerouslySetInnerHTML={{ __html: post.renderedHtml }} />
      <button disabled={isLiking} onClick={handleLike}>
        Beğen ({post.likeCount})
      </button>
    </article>
  );
}

// vite.config.ts — code-splitting Rollup'a devredilir
export default {
  build: {
    rollupOptions: {
      output: { manualChunks: { vendor: ['react', 'react-dom', 'react-router'] } },
    },
  },
};

Sonuç

İçerik-ağır, SEO-kritik yüzeylerde RSC ölçülebilir kazanç veriyor: react.dev'in örneğinde 75K gzip'lik kütüphane client'a hiç gitmiyor. Yoğun-interaktif iç panellerde (dashboard, admin) client-first hem daha basit hem daha az hata yüzeyi sunuyor. Kritik uyarı gerçek: Server'dan Client'a tam obje prop'u geçmek objenin tüm alanlarını flight payload'a yazdırır; sınırı yanlış çizersen kazanç sessizce erir. Kararı ölçümle ver, moda ile değil.

Ücretsiz Danışmanlık Al
SSS

Sıkça Sorulan Sorular

İçerik-ağır, SEO-kritik, ilk-yükleme (LCP/TTI) önemli yüzeylerde (blog, ürün sayfası, karşılaştırma sayfası) RSC ölçülebilir kazanç sağlar — sunucu tarafında veri çekme ve daha az client JS. Next.js 16.3'ün kendi verilerine göre sunucu tarafı render'da Node.js native stream'lerine geçişle yük altında %22 daha fazla istek işlenebiliyor. Yoğun-interaktif iç panellerde (dashboard, admin) client-first genelde daha basit bir geliştirme deneyimi sunar.

Giriş

"React Server Components" (RSC) bir render mimarisi/protokol; "Client-side React (SPA)" ise React'in klasik, tarayıcıda hydrate/render eden kullanım biçimi. İkisi rakip kütüphaneler değil — React'in kendisi ikisini de destekliyor; ayrım framework/bundler seçimine (Next.js App Router = RSC-native; Vite + React Router v7'nin client-first kullanımı) ve proje mimarisine dayanıyor. react.dev'in kendisi bunu açıkça söylüyor: yeni bir framework önerilirken bile 'tüm bu framework'ler CSR/SPA/SSG'yi de destekliyor, sunucu zorunlu değil' — yani RSC vs SPA aslında 'hangi framework' değil 'hangi render stratejisi, hangi route için' sorusu. 2026'da bu soru daha da aciliyet kazandı: Next.js 16.3 (3 Ağustos 2026) Instant Navigations ile RSC üzerine SPA-hissi vaat ediyor, Turbopack chunking analizi (3 Eylül 2026) client bundle dengesini yeniden şekillendirdi. Karar artık 'hangisi modern' değil, 'hangisi bu yüzey için doğru' sorusu — dokuz kriter üzerinden ölçüyoruz.

Karşılaştırma Matrisi

Karşılaştırma Matrisi: React Server Components / Client-side React (SPA)
ÖzellikReact Server ComponentsClient-side React (SPA)
Render konumuSunucuda önceden render (bundling öncesi)Tarayıcıda render (hydration)
İlk yük client JSDüşük — ağır kütüphaneler sunucuda kalabilir (Öne çıkan)Yüksek — tüm UI kodu tarayıcıya iner
İlk yükte görünür içerikHTML anında (JS beklemeden) (Öne çıkan)JS çalışana kadar boş/skeleton
Veri çekme modeli (ilk render)Sunucuda await, waterfall'sız (Öne çıkan)useEffect zinciri, waterfall riski
Client-side navigasyon veri modeliRSC Payload prefetch/cacheDoğrudan client fetch
Serileştirme sınırı riskiVar — 'use client' prop'ları serileşmeliYok — state doğrudan JS objesi (Öne çıkan)
Mental model basitliğiKarmaşık — server/client sınırı düşünülmeliBasit — her şey client'ta interaktif (Öne çıkan)
Framework bağımlılığıYüksek (Next.js App Router, RSC semver-dışı)Düşük (Vite + herhangi bir router) (Öne çıkan)
Cache/ISR entegrasyonuFramework-native (Next.js ISR) (Öne çıkan)Ayrı kütüphane gerekir (TanStack Query)
Debugging yüzeyiİkili (server + client)Tek (yalnız tarayıcı) (Öne çıkan)
Statik hosting/CDN deploySunucu koşturmak gerekir (veya SSG'ye düşer)Doğrudan CDN'e deploy edilebilir (Öne çıkan)
Güvenlik açığı geçmişi (2025-2026)Aralık 2025 kritik RCE (yamalı) + Ağustos 2026 Next.js yamalarıRSC'yi açmadığın sürece bu yüzey devreye girmiyor (Öne çıkan)
Framework/tooling repo yıldızı (23 Eyl 2026; React 250.668★ ikisinde de ortak)Next.js 142.408★Vite 82.964★
2026 aktif geliştirme odağıNext.js 16.3 Instant Navigations, Turbopack chunkingReact 19.3 View Transitions, Fragment Refs

Derinlemesine İnceleme

React Server Components

Genel Bakış

React Server Components, bundling öncesi ayrı bir ortamda önceden render edilen yeni bir bileşen türü olarak react.dev'de tanımlanıyor — client'a hiç JS göndermeden sunucuda çalışıp yalnız sonucu (RSC Payload) yollar. Next.js App Router bu resmi spesifikasyonu tam uyguluyor; React Router v7 ve Waku gibi alternatif framework'ler de opsiyonel RSC desteği sunuyor. İlk yükte sıra HTML → RSC Payload → JS hydration şeklinde işliyor: kullanıcı JS hiç çalışmadan anlamlı içerik görüyor. Next.js 16.3 (3 Ağustos 2026), Instant Navigations paketiyle server-driven modelin client-driven SPA duyarlılığını kaybetmemesini hedefliyor; Turbopack'in 3 Eylül 2026 chunking analizi client bundle tarafını RSC'den bağımsız optimize ediyor. RSC alttaki API'leri semver izlemediği için framework'e sıkı bağımlılık gerektiriyor.

Ekosistem

Paket yöneticisi
npm/pnpm (framework üzerinden — Next.js create-next-app)
Geliştirme ortamı
VS Code + React/TS extensionWebStorm
Popüler kütüphaneler
Next.js App RouterReact Router v7 (RSC deneysel)WakuPrisma (server-side data)Zod (server action validation)
GitHub yıldızı
142,408

Client-side React (SPA)

Genel Bakış

Client-side React, React'in orijinal ve hâlâ en yaygın kullanım biçimi — her component tarayıcıda render edilir, state tarayıcı belleğinde yaşar, sunucu yalnız bir JSON/REST/GraphQL API'si olarak görev yapar. Vite (2020), bu modelin referans tooling'i haline geldi: Rollup tabanlı production build, esbuild tabanlı dev-server ile hızlı HMR sunuyor. React'in kendisi bu modeli terk etmiyor — react.dev'in resmi framework önerisi sayfası bile 'tüm önerilen framework'ler CSR/SPA/SSG'yi de destekler, sunucu zorunlu değil' diyor. React Router v7, Shopify tarafından bakımı yapılıyor ve Vite ile eşleştiğinde tam bir client-first framework'e dönüşüyor. Client-first mimarinin asıl gücü basitlik: sunucu/client sınırı veya flight payload gibi ek bir mental model katmanı yok — her component varsayılan olarak interaktif olabilir, karar mimari değil kullanım anında verilir.

Ekosistem

Paket yöneticisi
npm/pnpm + Vite
Geliştirme ortamı
VS Code + React/TS extensionWebStorm
Popüler kütüphaneler
ViteReact Router v7TanStack QueryZustandReact Testing Library
GitHub yıldızı
82,964

Teknik Analiz

Client JS bundle boyutu

RSC lehine en güçlü, ölçülebilir argüman burada. react.dev'in kendi örneği: markdown render eden statik bir sayfa, Server Component olmadan marked + sanitize-html kütüphanelerinin 75K gzip'li ekstra bundle'ını client'a gönderiyor; Server Component ile bu kütüphaneler hiç client bundle'a girmiyor, yalnız render edilmiş HTML gidiyor. Ancak sınır net değil: 'use client' bir dosyayı işaretlediğinde o dosyanın TÜM transitive import'ları client bundle'a dahil oluyor — yani sınırı yanlış çizmek (büyük bir wrapper'a 'use client' koymak) kazancı sessizce yok edebilir. Client-first SPA'da (Vite tabanlı projelerde) ise bundle zaten tek parça bir uygulama mantığına yakındır; Next.js'in Turbopack chunking analizi bunun tam da neden sorunlu olduğunu gösteriyor: tek chunk her sayfada gereksiz kod taşır, sayfa-başı chunk paylaşılan kodu (ör. footer) tekrar tekrar indirtir, modül-başı chunk ise yüzlerce network isteği yaratır. Turbopack bu üçünü chunk-group + navigasyon-olasılığı ağırlıklandırmasıyla birleştiriyor — bu optimizasyon RSC'den bağımsız, saf client bundle sorunu; yani SPA tarafı da bu problemi framework tooling'iyle (Vite'ın Rollup code-splitting'i dahil) çözmek zorunda.

LCP / TTI ve ilk yükleme davranışı

Next.js dokümantasyonuna göre ilk yükte sıra HTML → RSC Payload → JS hydration şeklinde işliyor — yani kullanıcı JS hiç çalışmadan anlamlı HTML görüyor. Saf client-side SPA'da ise ilk yük genelde boş <div id="root"> + JS bundle indirilip çalışana kadar boş ekran/skeleton'dur; bu yüzden TTI ile FCP birbirine yakınsar (JS olmadan hiçbir şey görünmez). Next.js 16.3, bu ikisini birbirine yaklaştırmaya çalışıyor: Instant Navigations paketiyle server-driven modelin avantajlarını kaybetmeden client-driven SPA'nın duyarlılığını (responsiveness) hedefliyor — bu, sektörün RSC ile SPA arasındaki LCP/TTI farkının hâlâ gerçek ve aktif çözülmeye çalışılan bir problem olduğunun resmi kanıtı. React 19.2'nin <Activity> bileşeni de aynı boşluğu React seviyesinde kapatıyor: navigasyon öncesi hedef sayfayı arka planda hazırlayıp (data/css/image preload) 'hidden' tutarak, SPA'daki anlık geçiş hissini server-driven mimaride simüle ediyor. Buna karşılık, React 19.3 (9 Eylül 2026) View Transitions API'sini React'e taşıyarak client-first tarafında da benzer akıcı geçişleri framework'ten bağımsız hale getirdi — yarış tek yönlü değil, iki taraf da birbirinin avantajını kopyalıyor.

RSC payload (flight) boyutu ve serileştirme tuzakları

Bu, kriterler arasında en teknik ve en riskli olanı. Resmi kaynak doğruluyor: 'use client' sınırından geçen değerler ya React component ya da desteklenen serileştirilebilir prop değerleri olmalı, aksi halde React exception fırlatıyor — yani tip güvenliği derleme zamanında değil, çoğunlukla çalışma zamanında yakalanıyor. Server Components sayfası ayrıca RSC Payload'ın neyi içerdiğini tanımlıyor: render edilmiş Server Component sonucu, Client Component placeholder'ları, JS dosya referansları ve Server'dan Client'a geçen props. Pratik sonuç: bir DB satırını olduğu gibi client component'e prop olarak geçirmek, o objenin kullanılan her alanını flight payload'a yazdırır — objeyi sunucuda daraltıp yalnız gereken alanları geçirmek gerekiyor. Client-side SPA'da böyle bir 'payload serileştirme' katmanı yok — state doğrudan JS objesi olarak tarayıcıda yaşıyor, bu tuzak da yok, ama karşılığında her state client'ta yeniden hesaplanıyor veya ayrıca fetch ediliyor. Ayrıca RSC'nin alttaki API'leri React minörleri arasında semver izlemiyor — framework/bundler spesifik sürüme pinlenmek zorunda, bu da versiyon yükseltmelerini SPA'ya göre daha kırılgan yapıyor.

Veri çekme modeli ve waterfall riski

react.dev'in Note/Author örneği klasik SPA waterfall'ını gösteriyor: Note component useEffect ile fetch ediyor, o bitince Author component kendi useEffect'inde ikinci bir fetch başlatıyor — sıralı, yavaş. Server Component versiyonunda ikisi de await ile sunucuda, veri kaynağına yakın, doğrudan render sırasında okunuyor; RSC mimarisi bunu server-centric request/response modeliyle client-centric SPA'nın interaktifliğini birleştiren yeni bir mimari olarak tanımlıyor. Ancak bu avantaj yalnızca sunucu tarafı ilk render için tam geçerli — client-side navigasyonlarda RSC Payload prefetch/cache ediliyor ve Client Component'lar tamamen client'ta, sunucu HTML'i olmadan render ediliyor. Yani 'waterfall'ı öldürme' argümanı en çok ilk sayfa yükünde, ISR/SSR sayfalarında güçlü; saf client route navigasyonlarında SPA ile RSC arasındaki fark küçülüyor. Next.js'in ISR mekanizması da bunu destekliyor: revalidate süresi dolunca eski (stale) sayfa anında servis edilirken arka planda yeniden üretiliyor — yüksek revalidate (ör. 1 saat) önerilerek waterfall riski daha da azaltılıyor.

İnteraktivite sınırı: 'use client' sınırının nereye çekildiği

Bu, RSC mimarisinde en çok mühendislik kararı gerektiren nokta. Kural açık: bir modül 'use client' ile işaretlenince o modül ve tüm transitive bağımlılıkları client'ta çalışır; ama Next.js ayrıca büyük UI parçalarını değil, spesifik interaktif bileşenleri işaretlemeyi tavsiye ediyor — örnek olarak bir <Layout> içindeki sadece <Search /> bileşenini client yapmak, geri kalan statik logo/nav'ı server'da bırakmak. Server Component'lar context oluşturamaz ve useState gibi interaktif API kullanamaz; React context da Server Component'ta desteklenmiyor. Client-side SPA'da böyle bir sınır yok — her component varsayılan olarak interaktif olabilir, karar mimari değil, kullanım anında verilir. Bu basitlik, RSC'nin öğrenme eğrisini ve kod-inceleme yükünü artıran asıl sebep: yeni bir ekip üyesi 'bu component nerede çalışıyor, hangi API'leri kullanabilirim' sorusuyla RSC'de sürekli karşılaşırken, SPA'da bu soru hiç sorulmuyor.

Framework bağımlılığı ve güvenlik yüzeyi

RSC'yi benimsemek, pratikte bir framework'e (çoğunlukla Next.js App Router) bağımlı olmak demek — RSC alttaki API'leri semver izlemediği için doğrudan React üzerine kendi RSC bundler'ını yazmak önerilmiyor. Bu bağımlılığın somut bedeli var: 3 Aralık 2025'te RSC'de kritik bir unauthenticated RCE açığı bulundu (React 19.0.1/19.1.2/19.2.1 ile yamalandı), 11 Aralık 2025'te ek DoS ve kaynak kodu ifşası açıkları kapatıldı; Next.js da ayrıca 25 Ağustos 2026'da 16.3.3 ve 15.5.24 sürümlerinde iki Critical önem dereceli açık kapattı — ikisi de RSC'ye özgü değil (AVIF image-optimization ve Windows-hosted RCE) ama framework bakım yükünün örneği. Client-side SPA'da (Vite + React Router v7) RSC'yi açmadığın sürece bu sunucu-tarafı bundler yüzeyi devreye girmiyor — dikkat et, resmi duyuru RSC kullanıldığında react-router ve @vitejs/plugin-rsc'yi de etkilenen sayıyor; RSC'siz saf SPA'da saldırı yüzeyi klasik REST/GraphQL API güvenliğine iniyor. Karşılığı var: React Router v7'nin RSC desteği hâlâ deneysel, yani SPA'da RSC'nin bundle/LCP kazanımlarından tam yararlanamıyorsun. Özetle: RSC = daha güçlü kazanç, daha büyük bakım/güvenlik yükümlülüğü; SPA = daha az kazanç, daha sade bakım yüzeyi.

Cache / ISR ile etkileşim ve ekip öğrenme eğrisi

Next.js'in ISR (Incremental Static Regeneration) mekanizması RSC ile doğal olarak entegre çalışıyor: revalidate süresi dolunca istek eski (stale) sayfayı anında alırken arka planda yeni sürüm üretiliyor; resmi doküman yüksek revalidate süresi (1 saniye yerine 1 saat gibi) öneriyor. Bu, RSC'nin cache katmanıyla derin entegrasyonunun bir sonucu — Partial Prefetching ve Instant Insights (Next.js 16.3) da aynı cache-first felsefeyi navigasyon deneyimine taşıyor. Client-side SPA'da cache katmanı genelde ayrı bir kütüphaneye (TanStack Query gibi) devredilir — framework kendisi bir cache stratejisi dayatmaz, ekip kendi cache invalidation kurallarını yazar. Öğrenme eğrisi açısından bu iki yaklaşım taban tabana zıt: RSC ekibi framework'ün cache/ISR sözleşmesini öğrenmek zorunda (ne zaman revalidate olur, hangi veri statik hangi veri dinamik), SPA ekibi ise kendi cache kütüphanesini seçip yapılandırmak zorunda. İkisi de 'ücretsiz' değil — sadece öğrenme yükü farklı yerde: RSC'de framework sözleşmesinde, SPA'da kütüphane seçimi ve yapılandırmasında.

Hangi Senaryoda Hangisi

Blog, dokümantasyon veya bu karşılaştırma sayfası gibi içerik-ağır, SEO-kritik sayfa

Öneri: RSC (Next.js App Router)

İlk yük HTML anında görünür, ağır render kütüphaneleri client bundle'a hiç girmez; SEO ve LCP doğrudan kazanır.

Yoğun-interaktif admin/dashboard paneli (sürükle-bırak, canlı filtre, sık state)

Öneri: Client-side React (SPA)

Serileştirme sınırı ve server/client mental model yükü olmadan hızlı iterasyon; debugging tek ortamda.

Küçük ekip, hızlı MVP, statik hosting bütçesi

Öneri: Client-side React (Vite)

Sunucu koşturma zorunluluğu yok, CDN'e doğrudan deploy edilir, öğrenme eğrisi düşük.

Yüksek trafikli, sık güncellenmeyen sayfa (ISR uygun)

Öneri: RSC + ISR

Revalidate dolunca stale sayfa anında servis edilir, arka planda yenilenir — sunucu maliyeti düşük kalır.

Mevcut büyük SPA codebase, kademeli modernizasyon

Öneri: Client-side React'te kal, ölçerek karar ver

RSC'ye geçiş framework değişimi ve mimari yeniden yazım gerektirir; kazanç ölçülmeden büyük yeniden yazım riskli.

Güvenlik/uyum ekibi sunucu-tarafı ek çalışma zamanı riskini minimize etmek istiyor

Öneri: Client-side React + klasik REST/GraphQL API

RSC bundler'ının kendine özgü güvenlik yüzeyi (Aralık 2025 RCE örneği) yok; saldırı yüzeyi API katmanına indirgenir.

Yeni proje, ekip Next.js App Router'ı zaten biliyor

Öneri: RSC varsayılan, gerekli yerlerde 'use client'

Next.js'in önerdiği yaklaşım budur; spesifik interaktif bileşenleri işaretlemek, büyük parçaları değil.

Yaygın Tuzaklar

  • Büyük bir wrapper component'e 'use client' koymak — tüm transitive import'lar client bundle'a dahil olur, RSC'nin bundle kazancı sessizce yok olur

    React Server Components

    Çözüm

    'use client' sınırını mümkün olduğunca yaprağa (spesifik interaktif bileşene) yakın çiz; statik logo/nav gibi kısımları server'da bırak

  • Server Component'ten Client Component'e ham bir DB objesini olduğu gibi prop olarak geçirmek — objenin kullanılan tüm alanları flight payload'a yazılır

    React Server Components

    Çözüm

    Sunucuda objeyi daraltıp yalnız gereken alanları içeren yeni bir obje geçir; gereksiz alanları client'a hiç gönderme

  • SPA'da veri çekmeyi sıralı useEffect zincirlerine bırakmak — Note→Author gibi bağımlı fetch'ler client-server waterfall yaratır

    Client-side React (SPA)

    Çözüm

    Paralel fetch (Promise.all) kullan veya TanStack Query gibi bir veri katmanıyla bağımlılıkları açıkça yönet

  • Server Component içinde useState/context oluşturmaya çalışmak — React context Server Component'ta desteklenmiyor

    React Server Components

    Çözüm

    Context provider'ı ayrı bir Client Component modülünden import edip Server Component'te render et

  • RSC'nin alttaki API'lerini semver bekleyerek React minör sürümü yükseltmek — RSC API'leri semver izlemiyor, minörler arası kırılabilir

    Her ikisi

    Çözüm

    Framework/bundler'ın (Next.js) önerdiği React sürümüne sıkı pinle, bağımsız React yükseltmesi yapma

Geçiş Kılavuzu

Client-side React (SPA) → RSC (Next.js App Router)

Tahmini süre: Küçük proje (5-10 route): 1-3 hafta. Orta (20-50 route): 2-4 ay, kademeli sayfa-sayfa geçiş. Büyük (100+ route): 6-12+ ay, tam yeniden yazım yerine seçici geçiş önerilir.
  1. 1Mevcut SPA'daki route/ekranları audit et — hangileri içerik-ağır ve SEO-kritik (RSC adayı), hangileri yoğun-interaktif (client'ta kalmalı)
  2. 2Next.js App Router projesini kur, mevcut route'ları önce Client Component olarak ('use client' ile) birebir taşı — davranış değişmeden çalışsın
  3. 3İçerik-ağır sayfaları tek tek Server Component'e çevir: veri çekmeyi useEffect'ten sunucu tarafı await'e taşı
  4. 4Yalnız gerçekten interaktif alt bileşenleri (buton, form, canlı sayaç) ayrı dosyalara çıkarıp 'use client' ile işaretle
  5. 5Server'dan Client'a geçen prop'ları daralt — ham DB objesi yerine yalnız gereken alanları içeren yeni obje geçir
  6. 6ISR/cache stratejisini tanımla (revalidate süresi), yüksek trafikli ama az değişen sayfalarda yüksek revalidate tercih et
  7. 7Bundle analyzer + Lighthouse ile önce/sonra ölçüm al — kazanç yoksa o sayfayı client-first bırak, RSC'ye geçiş zorunlu değil

Gelecek Öngörüsü

React Server Components

RSC, React ekibinin resmi yönü: Next.js 16.3 (3 Ağustos 2026) Instant Navigations paketiyle server-driven modelin SPA duyarlılığına yaklaşmasını hedefliyor, Turbopack chunking analizi (3 Eylül 2026) client bundle tarafını da RSC ile uyumlu optimize ediyor. React 19.2 (1 Ekim 2025) Activity ve useEffectEvent ile navigasyon performansını React seviyesinde destekliyor. Riskler de somut: RSC API'leri semver izlemiyor ve framework'e sıkı bağımlılık gerektiriyor; Aralık 2025'teki kritik RCE açığı, framework'e bağımlı mimarilerin güvenlik bakımını sürekli takip gerektirdiğini gösterdi.

Client-side React (SPA)

Client-side React ölmüyor — react.dev'in kendi framework önerisi sayfası CSR/SPA'yı hâlâ resmi olarak destekliyor, React Router v7 (Shopify bakımında) Vite ile tam bir client-first framework sunuyor. React 19.3 (9 Eylül 2026) View Transitions ve Fragment Refs ile client tarafının da modernleşmeye devam ettiğini gösterdi — bu özellikler RSC'ye bağımlı değil, saf client-side kullanımda da çalışıyor. Trend: SPA framework'ten bağımsız kalmaya devam edecek, ama RSC'nin sunduğu ilk-yük kazanımlarını yakalamak için Vite ekosisteminin de kendi tooling'ini (code-splitting, prerender) geliştirmesi bekleniyor.

Altın Bilgi

RSC vs Client-side React tartışması 'hangisi daha modern' sorusuna indirgendiğinde yanlış cevaba varıyor. react.dev'in önerdiği her framework CSR/SPA/SSG'yi de destekliyor, sunucu zorunlu değil. Asıl soru şu: bu route, sunucuda önceden render edilmekten mi kazanıyor, yoksa client'ta interaktif kalmaktan mı? Cevap ölçümle geliyor — bundle analyzer'da kaç KB azaldığını görmeden geçmek, serileştirme sınırı ve yeni bir güvenlik yüzeyi (Aralık 2025 RCE) satın almak demek olabilir. Pratik kural: Server Component'e ham obje prop geçirmeden önce hangi alanların client'ta kullanıldığını sor — 'hepsi değil' ise objeyi sunucuda daralt, aksi halde flight payload'ın sessizce şişer.

İlgili Blog Yazıları

Tüm Yazıları Gör

İlgili İçerik