---
title: 'İstemcide Oluşturma'
source: 'https://academia.sh/tr/kurslar/olusturma-stratejileri/istemcide-olusturma'
course: 'Oluşturma Stratejileri ve Altyapı'
language: tr
updated: '2026-08-17T18:09:30+00:00'
license: 'CC BY-SA 4.0'
---

# İstemcide Oluşturma

İşaretlemenin tarayıcıda üretilmesi; boş kabuğun ne taşıdığı, ilk içeriğe kadar uzanan seri istek zinciri ve bu modelin ilk boyamada ödediği bedelle sonraki gezinmelerde kazandığı hız.

Bir önceki kurs uygulamanın iç mimarisini kurdu: adresler görünümlere eşlendi, durum
tek bir yerden yönetildi, veri katmanı isteği ve yeniden denemeyi üstlendi, formlar
doğrulama kurallarını paylaştı. Bütün bunlar uygulamanın **ne yaptığını** tanımlar.
Açıkta kalan soru şudur: bu uygulamanın kullanıcıya gönderilen işaretlemesi **nerede** ve
**ne zaman** üretilir?

Kuzey Yamaç Ölçüm İstasyonu sitesi bu soruyu somutlaştırır. Sitede bir istasyon tanıtım
sayfası, dakikada bir değişen bir ölçüm listesi, geçmiş günlerin binlerce arşiv sayfası ve
istasyon sorumlusuna özel bir panel vardır. Bu sayfaların hepsi aynı yerde üretilmek
zorunda değildir. Bu kurs, her biri için ayrı bir karar verir. İlk model, işaretlemeyi
tarayıcıya ürettirendir.

## Oluşturma Kararı Nedir, Ne Değildir

**Oluşturma (rendering)**, bu kursta veri ile şablonun birleşip HTML işaretlemesine
dönüşmesi anlamına gelir. Karar, bu birleşmenin hangi makinede ve hangi anda olduğuna
ilişkindir: kullanıcının tarayıcısında mı, isteğe yanıt veren sunucuda mı, yoksa istek
gelmeden çok önce derleme sırasında mı.

Bu, Tarayıcı ve Web Platformu kursunda geçen **çizim hattı** ile karıştırılmamalıdır.
Çizim hattı, tarayıcının elindeki işaretlemeyi yerleşim, boyama ve bileşim aşamalarından
geçirip piksele çevirmesidir; işaretleme hangi makinede üretilmiş olursa olsun bu hat
tarayıcıda çalışır. Oluşturma kararı hattın **girdisinin** nereden geldiğini belirler,
hattın kendisini değiştirmez.

Ayrımı korumak için kurs boyunca iki sözcük ayrı tutulur: işaretlemenin üretilmesi
**oluşturma**, tarayıcının piksele çevirmesi **çizim**.

## Sunucunun Gönderdiği Şey

İstemcide oluşturmada sunucu, veri içermeyen bir belge ve bir betik gönderir. Belgenin
görevi betiği yüklemek ve betiğin yazacağı boş bir kap sağlamaktır.

```js
// istemci-sunucu.mjs — istasyon sayfasini istemcide olusturan sunucu
import { createServer } from "node:http";

const OLCUMLER = [
  { zaman: "06:00", sicaklik: -4.2, nem: 72 },
  { zaman: "07:00", sicaklik: -3.8, nem: 70 },
  { zaman: "08:00", sicaklik: -2.1, nem: 66 },
];

const KABUK = `<!doctype html>
<html lang="tr"><head><meta charset="utf-8"><title>Kuzey Yamac Olcum Istasyonu</title>
<script src="/uygulama.js" defer></script></head>
<body><div id="istasyon"></div></body></html>
`;

const BETIK = `const kok = document.getElementById("istasyon");
const yanit = await fetch("/api/olcumler");
const olcumler = await yanit.json();
kok.innerHTML = "<h1>Kuzey Yamac Olcum Istasyonu</h1><ul>" +
  olcumler.map((o) => "<li>" + o.zaman + " " + o.sicaklik + " C, %" + o.nem + "</li>").join("") +
  "</ul>";
`;

const bekle = (ms) => new Promise((c) => setTimeout(c, ms));

createServer(async (istek, yanit) => {
  yanit.sendDate = false; // ciktiyi belirlenimci kilmak icin Date basligi yazilmaz
  if (istek.url === "/") {
    yanit.setHeader("Content-Type", "text/html; charset=utf-8");
    yanit.setHeader("Content-Length", Buffer.byteLength(KABUK));
    yanit.writeHead(200).end(KABUK);
  } else if (istek.url === "/uygulama.js") {
    yanit.setHeader("Content-Type", "text/javascript; charset=utf-8");
    yanit.setHeader("Content-Length", Buffer.byteLength(BETIK));
    yanit.writeHead(200).end(BETIK);
  } else if (istek.url === "/api/olcumler") {
    await bekle(40); // veri kaynagindan okuma isi
    const govde = JSON.stringify(OLCUMLER);
    yanit.setHeader("Content-Type", "application/json");
    yanit.setHeader("Content-Length", Buffer.byteLength(govde));
    yanit.writeHead(200).end(govde);
  } else {
    yanit.writeHead(404).end();
  }
}).listen(8171, "127.0.0.1", () => console.log("dinleniyor: 127.0.0.1:8171"));
```

Aşağıdaki betik bu dosyayla aynı dizinde çalıştırılır. Bağlantı noktası olarak seçilen
8171 keyfîdir ve boş olmalıdır; kullanımdaysa iki dosyada da değiştirilir.

```bash
#!/usr/bin/env bash
# istemci-sunucu.mjs'yi baslatir, uc istegi sirayla olcer, sonra durdurur.
node istemci-sunucu.mjs > /dev/null &
sunucu=$!
sleep 1

BICIM='  ilk bayt %{time_starttransfer} s   govde %{size_download} B\n'

echo "--- ilk belgenin govdesi ---"
curl -sS http://127.0.0.1:8171/

echo "--- belgede olcum degeri geciyor mu? ---"
curl -sS http://127.0.0.1:8171/ | grep -c -- "-4.2"

echo "--- zincirin uc adimi (sirayla) ---"
echo "1) /"
curl -sS -o /dev/null -w "$BICIM" http://127.0.0.1:8171/
echo "2) /uygulama.js"
curl -sS -o /dev/null -w "$BICIM" http://127.0.0.1:8171/uygulama.js
echo "3) /api/olcumler"
curl -sS -o /dev/null -w "$BICIM" http://127.0.0.1:8171/api/olcumler

kill "$sunucu"
```

```
--- ilk belgenin govdesi ---
<!doctype html>
<html lang="tr"><head><meta charset="utf-8"><title>Kuzey Yamac Olcum Istasyonu</title>
<script src="/uygulama.js" defer></script></head>
<body><div id="istasyon"></div></body></html>
--- belgede olcum degeri geciyor mu? ---
0
--- zincirin uc adimi (sirayla) ---
1) /
  ilk bayt 0.000732 s   govde 199 B
2) /uygulama.js
  ilk bayt 0.000669 s   govde 300 B
3) /api/olcumler
  ilk bayt 0.042841 s   govde 130 B
```

Süre alanları çalıştırıldığı makineye ve o andaki yüke bağlıdır; her çalıştırmada farklı
çıkar. Anlamlı olan sayıların kendisi değil, aralarındaki orandır: ilk iki istek yerel
bağlantıda mikrosaniyeler sürerken üçüncüsü, yapay olarak eklenmiş 40 milisaniyelik veri
işi yüzünden yaklaşık altmış kat uzundur. Gerçek bir dağıtımda bu üç isteğin her birine
bir de ağ turu eklenir.

İkinci çıktı satırı modelin tanımlayıcı özelliğidir: ilk belgede hiçbir ölçüm değeri
yoktur. Belgeyi okuyan bir istemci — arama motoru gezgini, bağlantı önizlemesi üreten bir
hizmet, betik çalıştırmayan bir okuyucu — boş bir kap görür.

## Seri Zincirin Aritmetiği

Üç isteğin her biri bir öncekinin sonucuna bağlıdır. Belge gelmeden betiğin adresi
bilinmez; betik yürütülmeden veri isteği doğmaz. Bu bağımlılık, sürelerin toplanmasına yol
açar. Aşağıdaki hesap, ölçüm değil, açıkça yazılmış varsayımların aritmetiğidir.

```js
// zincir.mjs — istemcide olusturmanin ilk icerige kadar olan seri zinciri
// Girdiler varsayimdir; cikti bu varsayimlarin aritmetigidir, olcum degildir.
const GIDIS_DONUS = 60;      // ms, tek tur
const SUNUCU_BELGE = 5;      // ms, kabugu uretme isi
const SUNUCU_VERI = 40;      // ms, veri ucunun isi
const BANT = 1.5 * 1024;     // KB/s
const BETIK_KB = 180;
const YURUTME_MS_KB = 0.35;  // KB basina ayristirma + yurutme

const aktarim = (kb) => (kb / BANT) * 1000;

const adimlar = [
  ["belge istegi (tur)", GIDIS_DONUS],
  ["kabugu uretme", SUNUCU_BELGE],
  ["kabuk aktarimi (0.2 KB)", aktarim(0.2)],
  ["betik istegi (tur)", GIDIS_DONUS],
  [`betik aktarimi (${BETIK_KB} KB)`, aktarim(BETIK_KB)],
  ["betik ayristirma + yurutme", BETIK_KB * YURUTME_MS_KB],
  ["veri istegi (tur)", GIDIS_DONUS],
  ["veri ucunun isi", SUNUCU_VERI],
  ["veri aktarimi (0.1 KB)", aktarim(0.1)],
  ["agaci kurma + boyama", 8],
];

let toplam = 0;
console.log("adim".padEnd(30) + "sure".padStart(8) + "birikimli".padStart(12));
for (const [ad, sure] of adimlar) {
  toplam += sure;
  console.log(ad.padEnd(30) + sure.toFixed(1).padStart(8) + toplam.toFixed(1).padStart(12));
}
console.log("-".repeat(50));
console.log("ilk icerik boyamasi".padEnd(30) + toplam.toFixed(1).padStart(20));

// Kabukta gorunen sey: yalnizca ilk iki adimin sonunda bos bir belge.
const bosBelge = GIDIS_DONUS + SUNUCU_BELGE + aktarim(0.2);
console.log("bos kabuk ekranda".padEnd(30) + bosBelge.toFixed(1).padStart(20));
console.log("bos ekranda gecen oran".padEnd(30) +
  ((bosBelge / toplam) * 100).toFixed(0).padStart(19) + "%");
```

```
adim                              sure   birikimli
belge istegi (tur)                60.0        60.0
kabugu uretme                      5.0        65.0
kabuk aktarimi (0.2 KB)            0.1        65.1
betik istegi (tur)                60.0       125.1
betik aktarimi (180 KB)          117.2       242.3
betik ayristirma + yurutme        63.0       305.3
veri istegi (tur)                 60.0       365.3
veri ucunun isi                   40.0       405.3
veri aktarimi (0.1 KB)             0.1       405.4
agaci kurma + boyama               8.0       413.4
--------------------------------------------------
ilk icerik boyamasi                          413.4
bos kabuk ekranda                             65.1
bos ekranda gecen oran                         16%
```

Tabloda üç kalem baskındır: üç ağ turu, betiğin aktarımı ve betiğin yürütülmesi. Üçü de
kullanıcının gördüğü ilk içeriğin önünde durur. Kabuk ekrana geldiğinde toplam sürenin
yalnızca altıda biri geçmiştir; kalan beşte beşinde ekranda içerik yoktur.

Bu tablo aynı zamanda hangi iyileştirmenin ne kadar getirdiğini gösterir. Betiği yarıya
indirmek yaklaşık 90 milisaniye kazandırır. Veri isteğini belge isteğiyle birleştirmek bir
turu ve veri ucunun işini zincirin dışına çıkarır. Ağ turlarının süresi ise kod
değişikliğiyle azalmaz; mesafeye bağlıdır ve altıncı ders bu kalemi ayrıca ele alır.

## Modelin Kazandırdıkları

İlk yükleme pahalıdır, ama bedelin karşılığı vardır ve bu karşılık göz ardı edilirse model
haksız yere reddedilir.

Betik bir kez yürüdükten sonra **sonraki gezinmeler ağdan bağımsızlaşır**. Uygulama
Mimarisi kursunda kurulan istemci yönlendiricisi adres değiştiğinde yeni bir belge
istemez; eldeki durumdan yeni görünümü üretir. Ölçüm listesinden arşiv sayfasına geçiş,
belge indirmeden gerçekleşir.

Sunucu tarafı **durumsuz ve ucuzdur**. Sunucunun gönderdiği belge her kullanıcı için
aynıdır; kişiye göre değişen hiçbir şey üretmez. Böyle bir belge statik dosya olarak
sunulabilir, uzun ömürle önbelleklenebilir ve bir içerik dağıtım ağının kopyalarından
verilebilir.

**İstemci–sunucu sınırı belirgindir.** Sunucu yalnızca veri uçları sunar; işaretlemeyi
üretme sorumluluğu tümüyle istemcidedir. Aynı veri uçları bir masaüstü ya da mobil kabuk
tarafından da kullanılabilir; bu sınır, arayüzün çoğaltılmasını kolaylaştırır.

Uzun süre açık kalan, sık etkileşim alan ve her etkileşimde sunucuya dönmesi gerekmeyen
arayüzler bu modelin doğal alanıdır. İstasyon sorumlusunun paneli — ölçüm eşiklerini
düzenlediği, grafikleri yakınlaştırdığı, kayıtları süzdüğü ekran — buna örnektir.

## Bedelin Ağırlaştığı Yerler

Aynı ödünleşim, üç durumda modeli yanlış seçim hâline getirir.

**İlk ziyaretin sık olduğu sayfalarda** bedel her seferinde ödenir. Bir arama sonucundan
gelip tek sayfa okuyup ayrılan ziyaretçi, sonraki gezinmelerin hızından hiç
yararlanmaz; yalnızca ilk yüklemenin gecikmesini görür.

**İşaretlemeyi okuyan istemcilerde** içerik yoktur. Çıktının ikinci satırı bunu
göstermişti: belgede hiçbir ölçüm değeri geçmez. İçeriğin makine tarafından okunmasına
bağlı sayfalarda bu tek başına belirleyicidir.

**Yavaş aygıtlarda betiğin yürütülmesi** aktarımından pahalı hâle gelir. Tabloda 63
milisaniye görünen ayrıştırma ve yürütme kalemi, işlemci gücü birkaç kat düşük bir aygıtta
aynı oranda büyür; üstelik bant genişliği arttıkça bu kalem toplamın içinde daha büyük bir
pay tutar. Betiğin boyutu yalnızca indirme süresini değil, cihazın harcadığı işi de
belirler.

Dördüncü bir kırılganlık, betiğin hiç yürümemesidir. Aktarım kesilirse, bir hata betiği
durdurursa ya da bir uzantı araya girerse kullanıcının gördüğü şey boş bir belgedir. Sunucu
tarafında üretilmiş bir işaretlemede aynı arıza yalnızca etkileşimi kaybettirir, içeriği
değil.

## Özet

- Oluşturma kararı, veri ile şablonun hangi makinede ve hangi anda işaretlemeye
  dönüştüğünü belirler; tarayıcının çizim hattı bu karardan bağımsız olarak her durumda
  istemcide çalışır.
- İstemcide oluşturmada ilk belge veri taşımaz; ölçüm değerleri işaretlemede geçmez ve
  belgeyi betik çalıştırmadan okuyan istemciler boş bir kap görür.
- İlk içeriğe kadar olan yol seridir: belge, betik ve veri istekleri birbirini bekler;
  toplam süreye üç ağ turu, betiğin aktarımı ve betiğin yürütülmesi eklenir.
- Model, ilk yüklemeden sonra gezinmeleri ağdan bağımsızlaştırır ve sunucuyu durumsuz
  bırakır; uzun oturumlu, etkileşim yoğun ekranlar için uygundur.
- Bedel, ilk ziyaretin sık olduğu, işaretlemenin makine tarafından okunduğu ve aygıt
  gücünün düşük olduğu durumlarda ağırlaşır.

## Sonraki Adım

Bu dersteki zincirin üç ağ turundan ikisi, veri ile işaretlemenin ayrı ayrı taşınmasından
doğuyordu. İkisi tek yanıtta birleştirilirse zincir kısalır: sunucu, veriyi okuyup şablonu
kendisi işleyerek içeriği hazır gönderebilir. Bu, ilk içeriğin görünme anını öne çeker ama
sunucunun her istek için iş yapmasını gerektirir ve önbelleklenmesi kolay bir yanıtı
kişiye göre değişen bir yanıta dönüştürür. Sonraki ders bu takası ölçer: aynı istasyon
sayfası sunucuda üretildiğinde ilk bayt süresi, gövde boyutu ve içerik nasıl değişir.
