Site Hızı & Performans

    Sunucu Tarafı Render (SSR) Nedir

    SSR'ın çalışma mantığı, avantajları, hidrasyon maliyeti ve sunucu tarafı kurulumu.

    10 dk okuma Güncellendi: 25 Ağustos 2026

    Sunucu tarafı render (SSR), sayfanın HTML'inin kullanıcının tarayıcısında değil, sunucuda üretilip hazır biçimde gönderilmesidir. Kulağa yeni bir teknik gibi geliyor olabilir ama aslında web'in ilk günlerinden beri yapılan iştir: bir WordPress sayfası da, bir Django ya da Laravel sayfası da sunucu tarafı render'dır. Terimin son yıllarda tekrar öne çıkmasının sebebi, JavaScript çerçevelerinin bir dönem her şeyi tarayıcıda çizmeye yönelmesi ve bunun getirdiği hız ve SEO sorunlarının SSR'ı yeniden gündeme taşımasıdır.

    Bu yazıda SSR'ın akışını adım adım göstereceğim, istemci tarafı render ve statik üretimle farklarını netleştireceğim, "hidrasyon" denen ve SSR'ın görünmeyen maliyetini oluşturan adımı açıklayacağım. Ardından Node tabanlı bir SSR uygulamasının sunucuda nasıl doğru şekilde yayınlanacağını ve SSR'ı ayakta tutan asıl katman olan önbelleği yapılandırmayı anlatacağım.

    SSR Akışı Adım Adım#

    Bir kullanıcı SSR ile çalışan bir sayfayı istediğinde şu sıra izlenir:

    1. Tarayıcı sunucuya HTTP isteği gönderir.
    2. Sunucudaki uygulama isteği alır, ilgili yolu (route) çözer.
    3. Sayfa için gereken veriyi kaynağından çeker (veritabanı, API, dosya).
    4. Bileşen ağacını ya da şablonu çalıştırıp tam HTML üretir.
    5. HTML tarayıcıya gönderilir; tarayıcı içeriği hemen çizebilir.
    6. Ardından JavaScript paketi indirilir ve sayfa etkileşimli hale getirilir (hidrasyon).

    Kullanıcı açısından kritik nokta 5. adımdır: içerik, JavaScript'in indirilmesini beklemeden görünür. İstemci tarafı render'da ise 5. adıma ancak tüm paket indirilip çalıştırıldıktan ve veri ayrıca çekildikten sonra ulaşılır.

    Farkı görmek için sunucudan gelen ham yanıta bakmak yeterlidir:

    # JavaScript çalıştırmadan, sunucunun gerçekte ne gönderdiğini gör
    curl -s https://firmaniz.com/blog/ornek-yazi | grep -c "<h1"
    curl -s https://firmaniz.com/blog/ornek-yazi | wc -c
    
    # Yanıt süresini bileşenlerine ayır
    curl -s -o /dev/null -w "dns: %{time_namelookup}s  baglanti: %{time_connect}s  ttfb: %{time_starttransfer}s  toplam: %{time_total}s\n" \
      https://firmaniz.com/blog/ornek-yazi
    

    Ham HTML içinde başlıklar ve paragraflar varsa SSR (ya da statik üretim) yapıyorsunuz demektir. Boş bir kök öğe geliyorsa render tarayıcıda yapılıyor.

    SSR, CSR, SSG ve ISR Arasındaki Fark#

    Bu dört kısaltma sık karıştırılır. Aralarındaki tek ayrım, HTML'in ne zaman ve nerede üretildiğidir.

    YaklaşımHTML nerede üretilirNe zaman üretilirTipik TTFBUygun olduğu içerik
    CSR (istemci render)TarayıcıdaKullanıcı sayfayı açıncaÇok düşük (boş HTML)Panel, uygulama
    SSRSunucudaHer istekteOrtaSık değişen, kişiye özel
    SSG (statik üretim)Derleme makinesindeYayın öncesi bir kezÇok düşükBlog, tanıtım, dokümantasyon
    ISR / artımlı yenilemeSunucudaİlk istekte, sonra önbellektenDüşükBüyük katalog, haber

    Pratikte doğru soru "hangisi en iyi" değil, "bu sayfanın içeriği ne sıklıkta ve kime göre değişiyor" sorusudur. İçerik herkes için aynıysa ve saatte bir değişiyorsa SSR gereksiz bir maliyettir; statik üretim daha doğrudur ve nedenlerini statik site üreticilerinin hız avantajı yazısında ayrıntılandırdım. İçerik kullanıcıya göre değişiyorsa (sepet, panel, öneriler) SSR ya da istemci render kaçınılmazdır.

    Bir siteyi tek bir yaklaşıma mahkûm etmek zorunda da değilsiniz. Aynı site içinde blog sayfaları statik, ürün sayfaları SSR, kullanıcı paneli tamamen istemci tarafı olabilir. Bu karma yapı, modern kurulumların çoğunda karşılaştığım en sağlıklı düzendir.

    Hidrasyon: SSR'ın Görünmeyen Maliyeti#

    SSR'ın en yaygın yanlış anlaşılan tarafı şudur: sunucuda HTML üretmek, JavaScript maliyetinden kurtulduğunuz anlamına gelmez. Sayfa etkileşimli olacaksa, aynı bileşen kodu tarayıcıda da çalışmak zorundadır. Bu adıma hidrasyon denir.

    Hidrasyon sırasında tarayıcı JavaScript paketini indirir, ayrıştırır, bileşen ağacını yeniden kurar ve mevcut HTML'e olay dinleyicilerini bağlar. Bu süre boyunca kullanıcı sayfayı görür ama kullanamaz: düğmelere basar, bir şey olmaz. Kullanıcı deneyimi açısından en sinir bozucu durumlardan biridir çünkü sayfa hazır görünmektedir.

    Sonuç olarak SSR şu metrikleri iyileştirir ve şunları iyileştirmez:

    MetrikSSR'ın etkisiNeden
    FCP / LCPBelirgin iyileşmeİçerik ilk yanıtta gelir
    TTFBKötüleşirSunucu iş yapıyor
    TBT / INPDeğişmez ya da kötüleşirAynı JavaScript yine çalışır
    SEO / paylaşım kartıBelirgin iyileşmeBot HTML'i doğrudan okur

    Hidrasyon maliyetini azaltmanın üç pratik yolu vardır. Birincisi gönderilen JavaScript'i azaltmak; bu, hangi mimariyi seçerseniz seçin geçerli olan tek evrensel kuraldır. İkincisi kısmi hidrasyon: sayfanın tamamını değil yalnızca gerçekten etkileşim gereken bileşenleri canlandırmak. Üçüncüsü gecikmeli hidrasyon: bir bileşeni ancak ekrana girdiğinde ya da kullanıcı onunla etkileşime geçtiğinde canlandırmak.

    Bir de sık yapılan ve pahalı olan bir hata var: çift veri çekme. Sunucu veriyi çeker, HTML üretir; sonra tarayıcıda aynı bileşen yeniden çalışıp aynı isteği tekrar atar. Kullanıcı aynı veriyi iki kez indirir ve sayfa bir kez titrer. Çözüm, sunucuda çekilen veriyi HTML içine gömüp istemcinin onu kullanmasını sağlamaktır:

    <script type="application/json" id="baslangic-verisi">
    {"urunler":[{"id":1042,"ad":"Örnek Ürün","fiyat":249.9}],"sayfa":1}
    </script>
    

    İstemci tarafı bu düğümü okuyup doğrudan kullanır; ikinci bir API isteği atılmaz.

    Node Tabanlı Bir SSR Uygulamasını Yayınlamak#

    SSR uygulaması, statik dosyalardan farklı olarak sunucuda sürekli çalışan bir süreçtir. Bu, üç ek sorumluluk getirir: süreci ayakta tutmak, önüne bir ters vekil koymak ve kaynak kullanımını sınırlamak.

    Basit bir SSR sunucusunun iskeleti şöyle görünür:

    // sunucu.js — sadece iskelet; render fonksiyonu çerçevenize göre değişir
    import http from 'node:http';
    import { sayfayiUret } from './render.js';
    
    const sunucu = http.createServer(async (istek, yanit) => {
      try {
        const html = await sayfayiUret(istek.url);
        yanit.writeHead(200, {
          'Content-Type': 'text/html; charset=utf-8',
          // Ters vekilin önbelleklemesi için açık talimat
          'Cache-Control': 'public, max-age=0, s-maxage=600',
        });
        yanit.end(html);
      } catch (hata) {
        console.error('render hatasi', hata);
        yanit.writeHead(500, { 'Content-Type': 'text/html; charset=utf-8' });
        yanit.end('<h1>Gecici bir hata olustu</h1>');
      }
    });
    
    sunucu.listen(3000, '127.0.0.1');
    

    Dikkat edin: uygulama 127.0.0.1 üzerinde dinliyor, 0.0.0.0 üzerinde değil. SSR süreci doğrudan internete açılmamalıdır; TLS sonlandırma, hız sınırlama ve önbellek işini önündeki Nginx yapar.

    Süreci systemd ile yönetmek, üretimde en dayanıklı yoldur:

    ; /etc/systemd/system/ssr-uygulama.service
    [Unit]
    Description=SSR uygulama sunucusu
    After=network.target
    
    [Service]
    Type=simple
    User=uygulama
    WorkingDirectory=/var/www/firmaniz-ssr
    ExecStart=/usr/bin/node sunucu.js
    Restart=always
    RestartSec=5
    Environment=NODE_ENV=production
    ; Bellek sızıntısına karşı üst sınır
    MemoryMax=1G
    
    [Install]
    WantedBy=multi-user.target
    
    sudo systemctl daemon-reload
    sudo systemctl enable --now ssr-uygulama
    sudo systemctl status ssr-uygulama
    journalctl -u ssr-uygulama -f      # canlı log izleme
    

    Restart=always ve MemoryMax satırları önemlidir: SSR uygulamaları, her istekte bileşen ağacı kurdukları için bellek sızıntılarına diğer sunucu türlerinden daha yatkındır. Sınır koymak, tek bir kaçak sürecin tüm sunucuyu takasa (swap) düşürmesini engeller.

    Önbellek: SSR'ı Ayakta Tutan Katman#

    SSR'ın CPU maliyeti her istekte ödenir. Bu maliyeti ortadan kaldırmanın yolu, üretilen HTML'i saklamaktır. Giriş yapmamış ziyaretçiler için aynı sayfanın çıktısı aynı olduğuna göre, onu her seferinde yeniden üretmenin bir anlamı yoktur.

    # Önbellek alanı tanımı (http bloğunda)
    proxy_cache_path /var/cache/nginx/ssr levels=1:2 keys_zone=ssr:20m
                     max_size=2g inactive=2h use_temp_path=off;
    
    server {
        listen 443 ssl;
        http2 on;
        server_name firmaniz.com;
    
        # Statik varlıklar doğrudan diskten; uygulamaya hiç gitmesin
        location /assets/ {
            root /var/www/firmaniz-ssr/public;
            expires 1y;
            add_header Cache-Control "public, immutable";
        }
    
        location / {
            proxy_pass http://127.0.0.1:3000;
            proxy_http_version 1.1;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
    
            proxy_cache ssr;
            proxy_cache_valid 200 301 302 10m;
            proxy_cache_valid 404 1m;
            # Aynı sayfa için eşzamanlı istekler tek üretimle karşılansın
            proxy_cache_lock on;
            # Uygulama hata verirse eski kopyayı sun
            proxy_cache_use_stale error timeout updating http_500 http_502 http_503;
    
            # Oturum çerezi taşıyan istekler önbelleği atlasın
            proxy_cache_bypass $cookie_oturum;
            proxy_no_cache     $cookie_oturum;
    
            add_header X-SSR-Cache $upstream_cache_status always;
        }
    }
    

    Bu yapılandırmadaki üç satır özellikle değerlidir. proxy_cache_lock on sayesinde aynı sayfaya aynı anda gelen yüz istek, uygulamada yüz ayrı render tetiklemez; biri üretir, diğerleri sonucu bekler. proxy_cache_use_stale uygulamanız çöktüğünde bile ziyaretçiye eski ama çalışan bir sayfa gösterir. proxy_cache_bypass ise giriş yapmış kullanıcıların birbirinin sayfasını görmesini engeller — bu satırı unutmak, SSR önbelleğinde yapılabilecek en tehlikeli hatadır.

    Etkiyi doğrulamak kolaydır:

    curl -sI https://firmaniz.com/blog/ornek-yazi | grep -i -E 'x-ssr-cache|cache-control'
    # X-SSR-Cache: MISS   (ilk istek)
    # X-SSR-Cache: HIT    (ikinci istek)
    

    Önbellek isabet oranınız yükseldikçe SSR'ın kapasitesi statik siteye yaklaşır. Kapasitenin nasıl hesaplanacağını eşzamanlı kullanıcı kapasitesi hesaplama, benzer bir önbellek kurgusunun PHP tarafındaki karşılığını Nginx FastCGI cache yapılandırma yazısında bulabilirsiniz.

    SSR'da Sık Yapılan Hatalar#

    Önbelleksiz yayına çıkmak. Geliştirme ortamında sorunsuz çalışan SSR uygulaması, gerçek trafikte CPU'yu tüketir. Önbellek katmanı bir iyileştirme değil, kurulumun parçasıdır.

    Kişiye özel içeriği önbelleğe almak. Kullanıcı adının göründüğü bir başlık çubuğunu önbelleklerseniz, bir sonraki ziyaretçi başkasının adını görür. Bu, veri sızıntısıdır. Kişiye özel parçaları ya istemcide doldurun ya da oturum çerezi olan istekleri önbellekten muaf tutun.

    Sunucuda tarayıcıya özel nesnelere erişmek. window, document ve localStorage sunucuda yoktur; bunlara erişen bir bileşen render sırasında hata fırlatır ve sayfa 500 döner. Bu tür kodu yalnızca hidrasyondan sonra çalışacak biçimde koşullayın.

    Zaman aşımı koymamak. SSR sırasında yapılan bir API çağrısı yanıt vermezse, render süreci beklemede kalır ve her yeni istek bir işçi daha tüketir. Sunucu tarafı veri çağrılarına mutlaka kısa bir zaman aşımı ve hata durumunda kısmi içerikle devam etme davranışı ekleyin.

    Her sayfayı SSR yapmak. İçeriği herkes için aynı olan ve seyrek değişen sayfaları SSR ile üretmek, bedava bir maliyettir. Onları statik üretin ya da önceden hazırlayın; nasıl yapılacağını prerender nedir, SEO'ya etkisi yazısında anlattım.

    Tek süreçle çalıştırmak. Node tek iş parçacıklıdır; çok çekirdekli bir sunucuda tek süreç çalıştırmak kapasitenizin büyük kısmını kullanmamak demektir. Çekirdek sayısı kadar süreç açıp önüne yük dengeleyici koyun.

    Sıkça Sorulan Sorular#

    SSR ile SSG arasındaki fark nedir#

    İkisi de HTML'i sunucu tarafında üretir ama zamanlaması farklıdır. SSG (statik üretim) sayfayı yayın öncesinde bir kez üretir ve ziyaretçilere hep aynı hazır dosyayı gönderir; içerik değiştiğinde yeniden derleme gerekir. SSR ise sayfayı her istekte yeniden üretir, dolayısıyla her zaman güncel ve kullanıcıya özel olabilir ama karşılığında sunucu CPU'su harcar. İçeriğiniz herkes için aynıysa ve seyrek değişiyorsa SSG, kullanıcıya göre değişiyorsa SSR doğru tercihtir.

    SSR SEO için gerekli mi#

    Zorunlu değil ama işi belirgin biçimde kolaylaştırır. Arama motorları JavaScript çalıştırabildiği için istemci tarafı render edilen sayfalar da indekslenir, ancak bu işlem gecikmeli yapılır ve sık güncellenen içerikte sorun yaratır. Sosyal medya önizleme botları ise JavaScript çalıştırmaz; SSR olmadan paylaşım kartlarınız sayfaya özel olmaz. İçerik odaklı bir sitede SSR ya da statik üretim, bu iki sorunu birden çözer.

    SSR sitemi yavaşlatır mı#

    TTFB'yi kesinlikle artırır, çünkü sunucu artık iş yapıyordur. Ancak kullanıcının hissettiği metrik olan LCP genellikle iyileşir, zira içerik JavaScript beklemeden görünür. Net sonuç, sunucunuzun render süresine bağlıdır: render 50 ms sürüyorsa kazanç açıktır, 800 ms sürüyorsa istemci render'dan bile kötü olabilirsiniz. Bu yüzden SSR ile önbellek her zaman birlikte kurulur.

    SSR için nasıl bir sunucu gerekir#

    Statik siteye göre daha fazlası: her istekte CPU harcandığı için işlemci gücü ve yeterli RAM önemlidir. Node tabanlı bir uygulama için çekirdek başına bir süreç çalıştırmayı planlayın ve süreç başına birkaç yüz megabayt bellek ayırın. Kritik olan nokta root erişimidir; systemd servisi tanımlamak, ters vekil kurmak ve önbellek yapılandırmak paylaşımlı hostingde mümkün değildir. Bu yüzden SSR kurulumları sanal ya da adanmış sunucuda yaşar.

    Hidrasyon hatası ne demek ve nasıl çözülür#

    Hidrasyon hatası, sunucunun ürettiği HTML ile tarayıcının aynı bileşenden ürettiği HTML'in birbirini tutmamasıdır. En yaygın sebepleri şunlardır: render sırasında tarih ya da rastgele sayı kullanmak (sunucu ve istemci farklı değer üretir), tarayıcıya özel nesnelere ilk render sırasında erişmek ve sunucu ile istemcide farklı veri kullanmak. Çözüm, ilk render'ın her iki tarafta da aynı çıktıyı üretmesini garanti etmek; değişken değerleri hidrasyondan sonraki adıma taşımaktır.

    WordPress SSR sayılır mı#

    Teknik olarak evet. WordPress her istekte PHP çalıştırıp HTML üretir ve tarayıcıya hazır sayfa gönderir; bu tam olarak sunucu tarafı render tanımına uyar. Terimin bugün daha çok JavaScript çerçeveleri bağlamında kullanılmasının sebebi, o dünyada bir dönem her şeyin tarayıcıda çizilmesi ve SSR'ın bir "geri dönüş" olarak konuşulmasıdır. Pratik sonucu şudur: WordPress için geçerli olan önbellek mantığı, Node tabanlı SSR için de neredeyse birebir geçerlidir.

    Kapanış#

    SSR, HTML'i doğru yerde üretmekle ilgilidir: sunucu içeriği hazır gönderir, kullanıcı beklemeden görür, arama ve paylaşım botları da aynı içeriği okur. Aklınızda kalması gereken dört madde: SSR LCP'yi iyileştirir ama TTFB'yi artırır, dolayısıyla önbellek isteğe bağlı değildir; hidrasyon JavaScript maliyetini ortadan kaldırmaz, yalnızca erteler; kişiye özel içeriği asla paylaşımlı önbelleğe koymayın; ve her sayfayı SSR yapmak yerine seyrek değişen sayfaları statik üretin.

    SSR bir uygulama sürecine, ters vekile ve önbellek katmanına ihtiyaç duyar; bunların hepsi root erişimi ister. Node uygulamanızı systemd ile yönetip önüne Nginx koyabileceğiniz VDS ve bulut sunucu paketlerimiz bu kurulum için uygundur; yüksek trafikli projelerde kaynakların hiç paylaşılmadığı dedicated sunucu seçeneklerine bakabilirsiniz. Ters vekil, önbellek ve süreç yönetimini sizin yerinize kurmamızı isterseniz sunucu yönetimi hizmetimiz tam olarak bu işi üstlenir.

    SSRRenderMimari

    Uygulamaya geçmeye hazır mısınız?

    NVMe SSD, ücretsiz SSL ve %99.9 uptime garantisiyle Clou.TR hosting ve sunucu çözümleriyle projenizi hayata geçirin.