---
title: 'Statik Site Üretimi'
source: 'https://academia.sh/tr/kurslar/olusturma-stratejileri/statik-site-uretimi'
course: 'Oluşturma Stratejileri ve Altyapı'
language: tr
updated: '2026-08-17T18:09:31+00:00'
license: 'CC BY-SA 4.0'
---

# Statik Site Üretimi

İşaretlemenin derleme zamanında üretilip dosyaya yazılması; aynı şablonun iki ayrı anda çağrılması, sayfa sayısıyla doğrusal büyüyen derleme süresi ve statik çıktının tazelik sınırı.

Sunucuda oluşturma, her istekte aynı işi yapmayı göze alır. İstasyonun arşiv sayfaları için
bu iş tümüyle tekrardır: bir günün ölçüm kayıtları o gün kapandıktan sonra değişmez, aynı
girdiden hep aynı işaretleme çıkar. Aynı çıktıyı veren bir hesabı her istekte tekrarlamak
yerine bir kez yapıp sonucu saklamak mümkündür.

Bu ders o kaymayı yapar: iş, isteğin geldiği andan **derleme anına** taşınır. Ölçülecek
olan, ilk bayt süresine ne kazandırdığı ve bedelin nereye yazıldığıdır.

## Şablon Aynı Kalır, Çağrıldığı An Değişir

Karşılaştırmanın anlamlı olması için iki yolun aynı şablonu kullanması gerekir. Şablon ve
veri kaynağı ayrı bir modüle konur; hem derleyici hem sunucu bunu çağırır.

```js
// sayfa.mjs — arsiv sayfasinin veri kaynagi ve sablonu; iki cagirani da bunu kullanir
export const bekle = (ms) => new Promise((c) => setTimeout(c, ms));

// Gunluk olcum kaydi: gunden belirlenimci olarak turetilir, veri kaynagi taklididir.
export function gununOlcumleri(gun) {
  return Array.from({ length: 24 }, (_, saat) => ({
    zaman: String(saat).padStart(2, "0") + ":00",
    sicaklik: (-8 + ((gun * 7 + saat * 3) % 130) / 10).toFixed(1),
    nem: 40 + ((gun * 11 + saat * 5) % 55),
  }));
}

export function sayfa(gun, olcumler) {
  const satirlar = olcumler
    .map((o) => `<tr><td>${o.zaman}</td><td>${o.sicaklik}</td><td>${o.nem}</td></tr>`)
    .join("");
  return `<!doctype html>
<html lang="tr"><head><meta charset="utf-8"><title>Kuzey Yamac - gun ${gun}</title></head>
<body><h1>Kuzey Yamac Olcum Istasyonu</h1><h2>Gun ${gun}</h2>
<table><thead><tr><th>Saat</th><th>Sicaklik</th><th>Nem</th></tr></thead>
<tbody>${satirlar}</tbody></table></body></html>
`;
}
```

Statik üretimi bir teknik değil bir **çağırma anı** kararı yapan şey budur: kodda değişen
hiçbir şey yoktur, yalnızca `sayfa` işlevinin ne zaman çalıştırıldığı değişir.

## Derleme Zamanında Üretim

Derleyici, üretilecek sayfaların listesini gezer ve her biri için şablonu çağırıp sonucu
diske yazar.

```js
// uret.mjs — arsiv sayfalarini derleme zamaninda uretir ve sureyi olcer
import { mkdirSync, rmSync, writeFileSync } from "node:fs";
import { gununOlcumleri, sayfa } from "./sayfa.mjs";

const CIKTI = "cikti";

function derle(sayfaSayisi) {
  rmSync(CIKTI, { recursive: true, force: true });
  mkdirSync(CIKTI, { recursive: true });
  const basla = performance.now();
  let bayt = 0;
  for (let gun = 1; gun <= sayfaSayisi; gun++) {
    const govde = sayfa(gun, gununOlcumleri(gun));
    writeFileSync(`${CIKTI}/gun-${gun}.html`, govde);
    bayt += Buffer.byteLength(govde);
  }
  return { sure: performance.now() - basla, bayt };
}

derle(50); // isinma turu: olcume girmez

console.log("sayfa".padStart(7) + "sure (ms)".padStart(12) + "sayfa basina (ms)".padStart(19) +
  "cikti (KB)".padStart(13));
let oncekiSure = null, oncekiSayi = null;
for (const n of [100, 500, 1000, 5000]) {
  const { sure, bayt } = derle(n);
  let oran = "";
  if (oncekiSure !== null) {
    oran = `   sayfa x${(n / oncekiSayi).toFixed(0)} -> sure x${(sure / oncekiSure).toFixed(1)}`;
  }
  console.log(String(n).padStart(7) + sure.toFixed(1).padStart(12) +
    (sure / n).toFixed(3).padStart(19) + (bayt / 1024).toFixed(0).padStart(13) + oran);
  oncekiSure = sure; oncekiSayi = n;
}
```

`node uret.mjs` komutu bu dosyayla aynı dizinde çalıştırılır ve yanına bir `cikti` dizini
yazar.

```
  sayfa   sure (ms)  sayfa basina (ms)   cikti (KB)
    100         5.6              0.056          136
    500        26.0              0.052          680   sayfa x5 -> sure x4.6
   1000        48.9              0.049         1361   sayfa x2 -> sure x1.9
   5000       267.7              0.054         6813   sayfa x5 -> sure x5.5
```

Süreler makineye, disk hızına ve o andaki yüke bağlıdır; her çalıştırmada farklı çıkar.
Okunması gereken sütun sonuncusudur: sayfa sayısı beş katına çıktığında süre de yaklaşık
beş katına çıkar. Derleme **doğrusaldır** ve sayfa başına düşen maliyet sabit kalır.

Bu ölçekte sayfa başına maliyet şablonun işlenmesinden çok dosya yazmaya gider. Sayfa sayısı
büyüdükçe ölçülen oranın beşin biraz üstüne çıkması bunun belirtisidir: dizin girdileri
çoğaldıkça dosya sistemi işi ucuzlamaz.

## İki Yol, Aynı Gövde

Aynı sayfa iki kaynaktan sunulup karşılaştırılabilir: diskteki dosya ve istek anında
çağrılan şablon.

```js
// statik-sunucu.mjs — ayni sayfayi iki yoldan sunar: diskteki dosya ve istek anindaki uretim
import { createServer } from "node:http";
import { readFile } from "node:fs/promises";
import { bekle, gununOlcumleri, sayfa } from "./sayfa.mjs";

const HTML = "text/html; charset=utf-8";

createServer(async (istek, yanit) => {
  yanit.sendDate = false;
  const statik = istek.url.match(/^\/statik\/gun-(\d+)\.html$/);
  const anlik = istek.url.match(/^\/istek-aninda\/gun-(\d+)$/);
  let govde;
  if (statik) {
    govde = await readFile(`cikti/gun-${statik[1]}.html`, "utf8");
  } else if (anlik) {
    await bekle(40); // veri kaynagindan gunun kayitlarini okuma isi
    govde = sayfa(Number(anlik[1]), gununOlcumleri(Number(anlik[1])));
  } else {
    return yanit.writeHead(404).end();
  }
  yanit.setHeader("Content-Type", HTML);
  yanit.setHeader("Content-Length", Buffer.byteLength(govde));
  yanit.writeHead(200).end(govde);
}).listen(8173, "127.0.0.1", () => console.log("dinleniyor: 127.0.0.1:8173"));
```

```bash
#!/usr/bin/env bash
# Once sayfalari uretir, sonra iki yolu ayni olcuyle karsilastirir.
node uret.mjs > /dev/null   # sayfalari uretir, tablosu ayrica calistirilir
node statik-sunucu.mjs > /dev/null &
sunucu=$!
sleep 1
curl -sS -o /dev/null http://127.0.0.1:8173/statik/gun-1.html   # isinma

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

echo "--- diskteki dosya ---"
curl -sS -o /dev/null -w "$BICIM" http://127.0.0.1:8173/statik/gun-7.html
echo "--- istek aninda uretim ---"
curl -sS -o /dev/null -w "$BICIM" http://127.0.0.1:8173/istek-aninda/gun-7

echo "--- iki govde ayni mi? ---"
curl -sS http://127.0.0.1:8173/statik/gun-7.html > a.html
curl -sS http://127.0.0.1:8173/istek-aninda/gun-7 > b.html
if cmp -s a.html b.html; then echo "ayni"; else echo "farkli"; fi
rm -f a.html b.html

kill "$sunucu"
```

```
--- diskteki dosya ---
  ilk bayt 0.000912 s   govde 1386 B
--- istek aninda uretim ---
  ilk bayt 0.042926 s   govde 1386 B
--- iki govde ayni mi? ---
ayni
```

Gövdeler bayt bayt aynıdır; ilk bayt süreleri arasında iki mertebe fark vardır — 0,0009
saniyeye karşı 0,0429 saniye. Kullanıcıya giden şey değişmemiştir, o şeyi üretme işi
zamanda geriye alınmıştır.

Farkın kaynağı, veri kaynağının 40 milisaniyelik işidir. Statik yolda bu iş derleme
sırasında bir kez yapılmıştır ve istek anında hiç yapılmaz. İstek anındaki üretimde ise her
istekte yeniden yapılır: bin ziyaretçi, bin kez aynı hesap demektir.

## Statik Çıktının Getirdikleri

Diskteki bir dosya olmanın, dosya olmaktan doğan sonuçları vardır.

**Sunucu çalıştırma zamanı gerektirmez.** Yanıt bir dosya okumasıdır; bir uygulama süreci,
bir veri kaynağı bağlantısı ya da bir çalışma zamanı ortamı olmadan verilebilir. Bu, bir
içerik dağıtım ağının çıktıyı olduğu gibi kopyalayıp sunabilmesi anlamına gelir.

**Yanıt herkes için aynıdır.** Aynı adres her istemciye aynı baytları verir; bu, yanıtın
paylaşımlı katmanlarda uzun ömürle saklanabilmesini sağlar. Önbellek Stratejileri dersindeki
ayrım burada en uygun tarafındadır: değişmeyen içerik, doğrulama isteği bile gerektirmeyen
içeriktir.

**Yük, istek hacminden bağımsızlaşır.** Sunucuda oluşturmada maliyet istek sayısıyla
büyürdü; statik üretimde maliyet **sayfa sayısıyla** büyür ve bir kez ödenir. On ziyaretçi
ile on bin ziyaretçi arasındaki fark, yalnızca bant genişliğidir.

**Hata yüzeyi daralır.** İstek anında çalışan kod yoksa, istek anında oluşacak hata da
yoktur. Bir şablon hatası derleme sırasında görünür ve yayına çıkmadan yakalanır.

## Nerede Uygulanamaz

Statik üretimin koşulu tektir: sayfanın çıktısı yalnızca **derleme anında bilinen
girdilere** bağlı olmalıdır. Bu koşul üç durumda bozulur.

Sayfa kullanıcıya göre değişiyorsa üretilemez. İstasyon sorumlusunun paneli her kişi için
farklıdır; derleme zamanında hangi kişi için üretileceği bilinmez.

İçerik derlemeler arasında değişiyorsa çıktı eskir. Canlı ölçüm listesi dakikada bir
değişir; günde bir kez derlenen bir dosya, gösterdiği değerin yaşını hiçbir zaman
bildiremez. Statik üretimde tazelik, derleme sıklığıyla sınırlıdır.

Sayfa sayısı derlemeyi taşıyamaz hâle geliyorsa yöntem tıkanır. Ölçülen doğrusallık iyi
haber gibi görünür ama doğrusal büyümenin sonu vardır: sayfa başına 0,05 milisaniye, yüz bin
sayfada beş saniye, bir milyon sayfada bir dakikanın üstü demektir. Gerçek bir derlemede
sayfa başına iş bu örnekten büyüktür ve tek bir yazım düzeltmesi için bütün sitenin yeniden
üretilmesi kabul edilemez hâle gelir.

Bu üçüncü sınır, statik üretimin kendi içinden çıkan bir soruya yol açar: bütün sayfaları
yeniden üretmeden yalnızca değişenleri tazelemek mümkün müdür?

## Özet

- Statik üretim, işaretlemeyi üreten şablonu istek anında değil derleme anında çağırır;
  şablonun kendisi değişmez.
- Ölçüm iki yolun gövdesinin bayt bayt aynı olduğunu, ilk bayt sürelerinin ise iki mertebe
  ayrıldığını gösterir; fark, veri kaynağının işinin zamanda öne alınmasıdır.
- Derleme süresi sayfa sayısıyla doğrusal büyür ve sayfa başına maliyet sabit kalır;
  toplam maliyet istek hacmine değil sayfa sayısına bağlıdır.
- Statik çıktı çalışma zamanı gerektirmez, herkese aynı yanıtı verir ve uzun ömürle
  önbelleklenebilir; istek anında çalışan kod olmadığı için hata yüzeyi daralır.
- Yöntem, çıktı derleme anında bilinmeyen girdilere bağlıysa, içerik derlemeler arasında
  değişiyorsa ya da sayfa sayısı derlemeyi taşıyamıyorsa uygulanamaz.

## Sonraki Adım

Üçüncü sınır, ikisinin arasında bir yer olduğunu düşündürür. Bir sayfa statik olarak
üretilmiş olabilir ama sonsuza kadar geçerli sayılmak zorunda değildir: kendisine bir
geçerlilik süresi tanınabilir, süre dolduğunda bir sonraki istek eski kopyayı alırken arka
planda yeni sürümü üretilebilir. Böylece hem çalışma zamanı maliyeti düşük kalır hem de
tazelik derleme sıklığına mahkûm olmaz. Sonraki ders bu düzeneği kurar ve ölçer: tazelik
penceresi, arka plan tazeleme kuyruğu, isabet ve ıska sayıları.
