Bak şimdi, “Sunucu bileşenleri olmadan streaming SSR olur mu?” sorusu ilk duyduğumda biraz tuhaf geldi açıkçası. Hani sektörün son iki yıldır kafasını çevirip baktığı yer tam olarak orasıydı ya… Ama işin aslı şu ki, evet, oluyor. Hem de bazı projelerde RSC’ye kıyasla daha sade, daha az kafa karıştırıcı ve — açık konuşayım — ekibe anlatması da bir tık daha kolay bir şekilde (ben de ilk duyduğumda şaşırmıştım)
Bi saniye — Ben bu konuyu ilk kez 2024 baharında, İstanbul’da orta ölçekli bir SaaS paneli üzerinde çalışırken kurcaladım (kendi tecrübem). Ekipteki ana dert şuydu: sayfanın üst kısmı hızlı geliyor ama alttaki raporlar yüzünden kullanıcı boş ekran görüyordu. Klasik SSR’da tüm veri bitmeden HTML çıkmıyordu. Streaming’e geçince tablo değişti; hızlı parça hemen geldi, ağır parçalar sonradan aktı. İşte fark tam da burada başlıyor.
Evet, doğru duydunuz.
İnanın, Bu yazıda sana React dünyasında streaming SSR’ın ne olduğunu, neden bazen RSC’den daha mantıklı olduğunu ve bunu server components kullanmadan nasıl kurabileceğini anlatacağım. Teoride değil, pratikte. Çünkü kağıt üstünde güzel duran şeyler üretimde çoğu zaman “eh işte”ye dönüyor (yanlış duymadınız)
Streaming SSR tam olarak neyi değiştiriyor?
Eh, Klasik SSR’da mantık basit. İstek gelir, sunucu tüm veriyi bekler, sonra komple HTML’yi gönderir. Sorun da zaten burada çıkıyor — tek bir yavaş API çağrısı varsa bütün sayfa onun temposuna mahkûm kalıyor. Mesela beş milisaniyelik cache sorgusu ile 2 saniyelik dış servis aynı potaya girince kullanıcı ikisini de bekliyor. Baya can sıkıcı.
Çok konuştum, örnekle göstereyim.
Streaming SSR bu zinciri kırıyor. Sunucu önce kabuğu gönderiyor; (söylemesi ayıp) yani header, menü, hızlı veriler… Sonra ağır parçalar geldikçe onları tek tek akıtıyor. Tarayıcı da boş oturmuyor; gelen bölümü ekrana basıyor, kullanıcı beklerken en azından bir şeyler görüyor. Bu hissiyat önemli çünkü algılanan hız bazen gerçek hızdan bile daha kıymetli oluyor. Hani ne farkı var diyorsunuz, değil mi? Gerçekten öyle.
Geçen yıl Kasım 2024’te Ankara’da bir fintech demosunda benzer yapı test ettim (kendi tecrübem). Analitik kartları gecikiyordu ama ana bakiye bilgisi anında gelince demo boyunca kimse “sayfa açılmadı mı?” diye sormadı. Küçük detay gibi duruyor. Ama UX tarafındaki etkisi baya büyük.
Bir dakika — bununla bitmedi.
Streaming SSR’ın olayı sadece performans değil; kullanıcının ekranda bir yaşam belirtisi görmesi. Bu küçük şey güven duygusunu ciddi şekilde artırıyor.
RSC’siz kurulumun üç yapı taşı
Şahsen, Bu modelin güzelliği şu: garip sihirler yok. Üç temel taş var ve hepsi tanıdık parçalar:
- Defer edilen veri: Hızlı olanları hemen çözüp yavaş olanları akışa bırakıyorsun.
- Suspense / Await sınırları: Sayfanın hangi bölümünün bekleyeceğini net çiziyorsun.
- Streaming SSR runtime: Sunucunun HTML’yi parça parça göndermesini sağlıyor.
Burada defer() mantığı çok kritik. Bir şeyi “hemen lazım”, diğerini “biraz sonra gelsin” diye ayırmazsan yine eski düzene geri dönersin. Yani mesele React yazmak değil; veri akışını düşünmek. Bu ikisi çok farklı şeyler aslında.
<Await> da güzel bir ayrım noktası veriyor (ki bu çoğu kişinin gözünden kaçıyor). Bir blok yüklenirken — itiraz edebilirsiniz tabi — skeleton gösteriyorsun, hazır olunca gerçek içerik geliyor. Kullanıcı açısından bu, market kasasında sıra ilerliyormuş hissi gibi — bekliyorsun ama en azından hareket var (inanın bana). Hareketsiz kuyruk başka bir şey, ilerleyen kuyruk başka.
Nerede işe yarar?
E-ticaret ürün sayfası düşün mesela. Fiyat ve stok hızlı gelir ama yorumlar yavaş olabilir. Haber sitelerinde manşet anında görünürken alt haber kutuları sonra akabilir. Dashboard’larda da aynı hikâye var; kritik metrikleri önce gösterip grafik hesaplarını arkadan sürüklemek baya işe yarar. Bu konuyla ilgili John Deere uzlaşması: Tamir hakkı için büyük kırılma yazımıza da göz atmanızı tavsiye ederim.
Açık konuşayım, Ama her yerde mucize bekleme. Eğer sayfanın tamamı tek bir API cevabına bağlıysa streaming seni kurtarmaz, sadece gecikmeyi biraz daha zarif sunar. Beklediğim kadar değildi — itiraz edebilirsiniz tabi — dediğim yerler oldu — özellikle kötü tasarlanmış backend’lerde akış var gibi görünür ama kullanıcı yine tık tık bekler. Mantıklı değil mi? Maalesef.
Pareto örneği üzerinden zihinde oturtalım
Kaynak yazıda kullanılan Pareto yaklaşımı işin soyut kısmını azaltıyor ve bunu seviyorum doğrusu. Çünkü birçok örnek “bakın Suspense süper” deyip — kendi adıma konuşayım — geçiyor; sonra geliştirici neyi nereye koyacağını kendi başına çözmeye çalışıyor, saatlerce. Burada ise loader içinde hızlı ve yavaş veriyi ayırıp page tarafında stream edilen alanları ayrı ele alıyorsun.
Garip gelecek ama, Bana göre bunun en iyi yani okunabilirlikten geliyor. İki ay sonra projeye yeni giren biri kodu açınca “bu veri niye burada await edilmiş?” sorusuna cevap bulabiliyor. Geçen sene Haziran ayında Berlin’de uzaktan çalışan bir ekipte buna benzer düzen kurmuştuk; teknik borcun azaldığını direkt hissettik çünkü karmaşa component ağacının içine gömülmemişti.
| Bölüm | Karmaşıklık | Kullanıcıya etkisi | Dikkat noktası |
|---|---|---|---|
| Kritik başlık / üst özet | Düşük | Anında görünür | Tüm deneyimi belirler |
| Ana içerik bloğu | Orta | Kademeli yüklenir | Skeleton kalitesi önemli |
| Ağır analitik / raporlar | Yüksek | Sona doğru gelir | Zaman aşımı yönetilmeli |
Kod tarafında fikir nasıl görünüyor?
// Mantık özeti
const data = defer({
fastValue: await getFastThing(),
slowValue: fetchSlowThing(),
})
// UI tarafı
<Await resolve={slowValue} fallback={<Skeleton/>}>
{(value) => <SlowSection data={value} />}
</Await>
// Mantık özeti
const data = defer({
fastValue: await getFastThing(),
slowValue: fetchSlowThing(),
})
// UI tarafı
<Await resolve={slowValue} fallback={<Skeleton/>}>
{(value) => <SlowSection data={value} />}
</Await>
Bunu okurken şöyle düşün: fastValue masaya hemen gelen çay gibi. slowValue ise mutfakta demlenen kahve — sonradan geliyor ama tadı orada gizli olabilir. Tabii düzgün hazırlanmışsa.
Avantajlar kadar sınırlar da var
Hani her parlak çözümün arkasında küçük bir gölge olur ya. Burada da var. Mesele sadece hız değil.
Birincisi, öğrenme eğrisi hafif azalıyor diyebilirim. Sıfırlanmıyor tabii — takımın defer/Suspense akışını gerçekten anlaması gerekiyor (buna dikkat edin). Anlamadan uygulamak, kopyala yapıştır düzeninde biter çoğu zaman. İkincisi hata yönetimi önemli hale geliyor; yavaş bölüm çökerse tüm ekran yerine yalnızca o blok hata vermeli, yoksa kazanılan puan boşa gider.
Bilmem anlatabiliyor muyum, Bir de şunu söyleyeyim: eğer backend’in zaten düzensizse streaming sadece düzenli kaos üretir. Performans kazancı almak için veri katmanını temiz tutman gerekiyor, yoksa tarayıcıya akan şey HTML değil stres oluyor resmen.
Küçük ekip ile kurumsal ekip farkı ne?
Küçük ekiplerde karar almak kolay. “Tamam bunu deneyelim” dersin, iki günde canlıya çıkarırsın. Kurumsalda ise olay biraz farklı — güvenlik incelemesi, observability araçları, cache stratejileri derken yol uzar. Ama enterprise tarafta kazanç da büyük; onlarca ekranın tamamında aynı yaklaşımı standardize edebilirsin. İşin tatlı tarafı bu. İşin yorucu tarafı da bu. Aynı anda iki şeydir yani. 2025’te Eskiyen Mimari Kararları: 4 Sessiz Tuzak yazımızda bu konuya da değinmiştik. Windows’ta Modern Standby Neden Kapatılır? Pil Gerçeği yazımızda bu konuya da değinmiştik.
Şuna dikkat: pratik noktalar
Bak şimdi burası önemli. Kodu yazmak kolay — asıl mesele işi sürdürülebilir yapmak.
İlk olarak skeleton tasarımını hafife alma. Kötü skeleton kötü UX demek. Kullanıcıya gri kutular göstermek yetmez; hangi alanın ne kadar süreceği konusunda sezgi vermelisin. İnce bir fark ama fark edilir. Flux-2-Pro Neden Dikkat Çekiyor? Görsel Üretimde Dengeli Güç yazımızda da bu konuya değinmiştik. Anthropic’in Yeni Ajan Mimarisi: Beyin ve Eller Ayrılıyor yazımızda da bu konuya değinmiştik.
İkinci nokta timeout meselesi. Dış API bazen sapıtıyor, bazen de hiç dönmüyor. O yüzden stream edilen her parçanın kendi hata eşiği olmalı. Peki bunu neden söylüyorum? Yoksa bir köşede sessizce bekleyen bir promise tüm sayfayı rehin alabilir.
Üçüncüsü ölçümleme. “Bence hızlandı” demek yerine TTFB, FCP, LCP gibi metriklere bak. Ben bunu Ağustos 2024’te Londra merkezli küçük bir danışmanlık projesinde test ettiğimde TTFB çok dramatik düşmedi ama FCP gözle görülür biçimde iyileşti. Kullanıcının hissettiği şey buydu zaten. Sayılar öyle söylüyor.
Şöyle ki, Bir de şu var: eğer içerikler birbirine aşırı bağımlıysa parçalamaya zorlama (buna dikkat edin). Bazı dashboard’larda bütün kartlar aynı sorgudan besleniyor; orada aşırı bölmek fayda yerine gecikme doğurabilir. Yani teknoloji moda diye uygulanmaz, işe yaradığı yerde uygulanır. Bu kadar.
Sıkça Sorulan Sorular
Streaming SSR ile klasik SSR arasındaki temel fark nedir?
Klasik SSR tüm HTML hazır olunca gönderir, streaming SSR ise hazır olan kısımları parça parça yollar. Böylece kullanıcı ilk içeriği daha erken görür.
SRC olmadan streaming SSR yapmak zor mu?
Zor olmak zorunda değil. Doğru loader yapısı. Suspense sınırlarıyla gayet yönetilebilir kalıyor; hatta bazı ekipler için RSC’den daha anlaşılır oluyor.
<Await> neden gerekli?
<Await>, stream edilen veriyi ilgili UI bloğuna bağlamak için kullanılır ve yüklenme sırasında fallback gösterir. Bu şekilde sayfa boş kalmaz.
Tüm uygulamalar için uygun mu?
Hayır, özellikle tüm verinin birbirine sıkı sıkıya bağlı olduğu yapılarda avantaj sınırlı kalabilir. En çok bağımsız veya kademeli yüklenebilen alanlarda işe yarar.
Kaynaklar ve İleri Okuma
Bak şimdi, React renderToPipeableStream Dokümantasyonu (buna dikkat edin)
Neyse uzatmayalım… Streaming SSR’ın özü şu: kullanıcıya beklemeyi hissettirmeden ilerleme göstermek istiyorsan bu yaklaşım baya güçlüdür!
Bu içerik işinize yaradı mı?
Benzer içerikleri kaçırmamak için beni sosyal medyada takip edin.



