---
title: 'Başarım Bütçesi'
source: 'https://academia.sh/tr/kurslar/frontend-kalitesi/basarim-butcesi'
course: 'Frontend Kalitesi'
language: tr
updated: '2026-08-17T18:09:22+00:00'
license: 'CC BY-SA 4.0'
---

# Başarım Bütçesi

Başarım kararlarının yazılı bir sınıra bağlanması; bütçe türleri, sınırın nereden türetildiği, derleme çıktısını denetleyen bir program ve iki derlemeyi karşılaştırarak gerilemenin yakalanması.

Önceki beş ders bir dizi iyileştirme kurdu: ölçütler tanımlandı, kritik yol kısaltıldı,
varlıklar boyutlandırıldı, ağ katmanı ayarlandı, çalışma zamanı boşaltıldı. Hepsinin ortak
açığı aynıdır — bir kez yapılmış olmaları.

Yeni bir özellik eklendiğinde paket büyür, bir kütüphane ortak parçaya girdiğinde tekrar
ziyaret kazancı erir. Erimenin bir sonraki yayında fark edilmesi gerekir. Bu ders o
mekanizmayı kurar.

## Bütçe Bir Hedef Değildir

İkisi karıştırılır ve karıştırıldığında bütçe işlevini yitirir.

**Hedef**, ulaşılmak istenen değerdir. Yönü vardır, yaptırımı yoktur; aşıldığında bir şey
olmaz.

**Bütçe**, aşılmasına izin verilmeyen sınırdır. Aşıldığında bir şey olur: derleme başarısız
sayılır, birleştirme durur, sürüm çıkmaz. Yaptırımı olmayan bir sayı bütçe değildir.

Ayrımın pratik sonucu şudur: bütçe, ulaşılabilir bir yerde çizilir. Şu anki değerin çok
altına konan bir sınır ilk günden kırmızı yanar ve kısa sürede yok sayılmaya başlar. Doğru
yaklaşım, sınırı bugünkü değerin biraz üstüne koymak ve zamanla indirmektir.

## Üç Bütçe Türü

Bütçeler ölçtükleri şeye göre ayrılır ve üçü de gerekir, çünkü her biri diğerinin
kaçırdığını yakalar.

**Ölçüt bütçesi** kullanıcı merkezli ölçütlere sınır koyar: en büyük içerik boyası şu
değerin altında kalacak, kümülatif düzen kayması şu puanı aşmayacak. Doğrudan deneyimi
ölçtüğü için en anlamlı bütçedir; en gürültülü olanı da budur, çünkü ölçüm koşullarına
duyarlıdır.

**Nicelik bütçesi** sayılabilir büyüklüklere sınır koyar: parça boyutları, istek sayısı,
görsel ağırlığı, yazı tipi dosyası sayısı. Belirlenimcidir — aynı derleme her zaman aynı
sayıyı üretir — ve bu yüzden yaptırıma en uygun bütçedir. Deneyimle bağı dolaylıdır: küçük
bir paket her zaman hızlı bir sayfa demek değildir.

**Kural bütçesi** sayı değil koşul içerir: ilk ekranda çizimi engelleyen dış biçem
bulunmayacak, belgede eşzamanlı betik olmayacak, en büyük içerik boyasına aday görsel
gecikmeli yüklenmeyecek. Bir sayıya indirgenemeyen kararları korur.

Sağlam bir düzen üçünü birleştirir: nicelik ve kural bütçeleri her derlemede, ölçüt
bütçesi düzenli aralıklarla denetlenir.

## Sınır Nereden Gelir

Bir sayının bütçe olabilmesi için gerekçesi olmalıdır. Üç gerekçelendirme yolu vardır.

**Ölçütün standart eşiğinden türetme.** İlk derste anılan sınıflandırma sınırları — en
büyük içerik boyası için iki buçuk saniye, kümülatif düzen kayması için sıfır virgül bir,
sonraki boyaya etkileşim için iki yüz milisaniye — doğrudan ölçüt bütçesi olarak
yazılabilir. Denetim yetmiş beşinci yüzdeliğe uygulanır.

**Ölçütten niceliğe geri hesap.** Hedef bir ölçüt değeri seçilir, hedef bir ağ ve aygıt
profili varsayılır, aradaki bütçe baytlara çevrilir. Kritik Oluşturma Yolu dersindeki
gidiş-dönüş modeli bu hesabın iskeletidir: kaç tur harcanabileceği belirlenince kaç bayt
gönderilebileceği çıkar.

**Bugünkü değerden pay bırakarak.** En pratik ve en az iddialı yol. Ölçülen değerin üzerine
küçük bir pay eklenir ve sınır oraya konur. Bu bütçe iyileştirme getirmez; **kötüleşmeyi
durdurur.** Çoğu takım için doğru başlangıç budur.

Hangi yol seçilirse seçilsin bütçe yazılı olmalı ve depoda durmalıdır. Kimsenin
göremediği bir sınır, olmayan bir sınırdır.

## Denetleyici

Aşağıdaki program bir derleme dökümünü bütçeyle karşılaştırır, sonra iki derlemeyi
karşılaştırıp gerilemeyi bildirir.

```js
// butce.mjs — parca boyutlarini butceyle karsilastirir ve iki derleme arasindaki gerilemeyi bulur

const KB = 1024;

// Butce: her grup icin toplama kurali, ust sinir (bayt) ve buyume toleransi (oran).
// "toplam" grubun tamamini olcer; "enBuyuk" gruptaki en agir tek parcayi olcer.
const BUTCE = {
  giris:  { toplama: "toplam",  sinir: 170 * KB, tolerans: 0.03 },
  ortak:  { toplama: "toplam",  sinir: 120 * KB, tolerans: 0.03 },
  rota:   { toplama: "enBuyuk", sinir:  45 * KB, tolerans: 0.05 },
  bicem:  { toplama: "toplam",  sinir:  40 * KB, tolerans: 0.05 },
};
const TOPLAM_SINIR = 360 * KB;

// Derleme dokumu: her parcanin adi, grubu ve sikistirilmis boyutu.
const oncekiDerleme = [
  { ad: "giris.4a1c.js",            grup: "giris", bayt: 148_112 },
  { ad: "ortak.9d02.js",            grup: "ortak", bayt: 101_760 },
  { ad: "rota-istasyonlar.1f77.js", grup: "rota",  bayt:  38_240 },
  { ad: "rota-olcum.55be.js",       grup: "rota",  bayt:  21_904 },
  { ad: "istasyon.6b3e.css",        grup: "bicem", bayt:  31_648 },
];

const yeniDerleme = [
  { ad: "giris.7e90.js",            grup: "giris", bayt: 151_296 },
  { ad: "ortak.c214.js",            grup: "ortak", bayt: 124_368 },
  { ad: "rota-istasyonlar.02ab.js", grup: "rota",  bayt:  39_120 },
  { ad: "rota-olcum.55be.js",       grup: "rota",  bayt:  21_904 },
  { ad: "rota-rapor.8c4d.js",       grup: "rota",  bayt:  17_856 },
  { ad: "istasyon.a9f1.css",        grup: "bicem", bayt:  32_960 },
];

const kb = (bayt) => `${(bayt / KB).toFixed(1)} KB`;

function gruplaraTopla(derleme) {
  const olcu = new Map();
  for (const [grup, { toplama }] of Object.entries(BUTCE)) {
    const parcalar = derleme.filter((p) => p.grup === grup).map((p) => p.bayt);
    olcu.set(grup, toplama === "enBuyuk"
      ? Math.max(0, ...parcalar)
      : parcalar.reduce((a, b) => a + b, 0));
  }
  return olcu;
}

const tumToplam = (derleme) => derleme.reduce((t, p) => t + p.bayt, 0);

// --- 1. Butce denetimi ---
function denetle(derleme, baslik) {
  const toplamlar = gruplaraTopla(derleme);
  let gecti = true;
  console.log(`--- ${baslik} ---`);
  console.log("grup".padEnd(8) + "kural".padEnd(9) + "boyut".padStart(11) +
    "sinir".padStart(11) + "kullanim".padStart(10) + "  sonuc");
  for (const [grup, { sinir, toplama }] of Object.entries(BUTCE)) {
    const boyut = toplamlar.get(grup);
    const kullanim = boyut / sinir;
    const sonuc = boyut <= sinir ? "gecti" : "KALDI";
    if (boyut > sinir) gecti = false;
    console.log(grup.padEnd(8) + toplama.padEnd(9) + kb(boyut).padStart(11) +
      kb(sinir).padStart(11) + `${(kullanim * 100).toFixed(1)}%`.padStart(10) + "  " + sonuc);
  }
  const genelToplam = tumToplam(derleme);
  const toplamSonuc = genelToplam <= TOPLAM_SINIR ? "gecti" : "KALDI";
  if (genelToplam > TOPLAM_SINIR) gecti = false;
  console.log("-".repeat(55));
  console.log("TOPLAM".padEnd(8) + "toplam".padEnd(9) + kb(genelToplam).padStart(11) +
    kb(TOPLAM_SINIR).padStart(11) +
    `${((genelToplam / TOPLAM_SINIR) * 100).toFixed(1)}%`.padStart(10) + "  " + toplamSonuc);
  console.log(`butce denetimi: ${gecti ? "gecti" : "KALDI"}\n`);
  return gecti;
}

denetle(oncekiDerleme, "onceki derleme");
const yeniGecti = denetle(yeniDerleme, "yeni derleme");

// --- 2. Gerileme tespiti: sinirin altinda kalan buyume de bildirilir ---
console.log("--- iki derlemenin karsilastirmasi ---");
const eski = gruplaraTopla(oncekiDerleme);
const yeni = gruplaraTopla(yeniDerleme);

console.log("grup".padEnd(8) + "onceki".padStart(11) + "yeni".padStart(11) +
  "fark".padStart(11) + "oran".padStart(9) + "  uyari");
const uyarilar = [];
for (const [grup, { tolerans }] of Object.entries(BUTCE)) {
  const a = eski.get(grup);
  const b = yeni.get(grup);
  const oran = (b - a) / a;
  const asildi = oran > tolerans;
  if (asildi) uyarilar.push(`${grup}: %${(oran * 100).toFixed(1)} buyume (tolerans %${tolerans * 100})`);
  console.log(grup.padEnd(8) + kb(a).padStart(11) + kb(b).padStart(11) +
    `${b - a >= 0 ? "+" : ""}${((b - a) / KB).toFixed(1)} KB`.padStart(11) +
    `${oran >= 0 ? "+" : ""}${(oran * 100).toFixed(1)}%`.padStart(9) +
    "  " + (asildi ? "TOLERANS ASILDI" : "-"));
}

// Yeni gelen parcalar ayrica bildirilir: adres degistigi icin ad karsilastirmasi
// icerik karmasi cikarilarak yapilir.
const kok = (ad) => ad.replace(/\.[0-9a-f]{4,}\./, ".");
const eskiAdlar = new Set(oncekiDerleme.map((p) => kok(p.ad)));
const yeniParcalar = yeniDerleme.filter((p) => !eskiAdlar.has(kok(p.ad)));

console.log(`\nyeni parcalar: ${yeniParcalar.map((p) => `${kok(p.ad)} (${kb(p.bayt)})`).join(", ") || "(yok)"}`);
if (uyarilar.length === 0) console.log("gerileme uyarisi: (yok)");
else {
  console.log("gerileme uyarisi:");
  for (const u of uyarilar) console.log(`  ${u}`);
}

const cikis = yeniGecti && uyarilar.length === 0 ? 0 : 1;
console.log(`\ncikis kodu: ${cikis}`);
process.exitCode = cikis;
```

```
--- onceki derleme ---
grup    kural          boyut      sinir  kullanim  sonuc
giris   toplam      144.6 KB   170.0 KB     85.1%  gecti
ortak   toplam       99.4 KB   120.0 KB     82.8%  gecti
rota    enBuyuk      37.3 KB    45.0 KB     83.0%  gecti
bicem   toplam       30.9 KB    40.0 KB     77.3%  gecti
-------------------------------------------------------
TOPLAM  toplam      333.7 KB   360.0 KB     92.7%  gecti
butce denetimi: gecti

--- yeni derleme ---
grup    kural          boyut      sinir  kullanim  sonuc
giris   toplam      147.8 KB   170.0 KB     86.9%  gecti
ortak   toplam      121.5 KB   120.0 KB    101.2%  KALDI
rota    enBuyuk      38.2 KB    45.0 KB     84.9%  gecti
bicem   toplam       32.2 KB    40.0 KB     80.5%  gecti
-------------------------------------------------------
TOPLAM  toplam      378.4 KB   360.0 KB    105.1%  KALDI
butce denetimi: KALDI

--- iki derlemenin karsilastirmasi ---
grup         onceki       yeni       fark     oran  uyari
giris      144.6 KB   147.8 KB    +3.1 KB    +2.1%  -
ortak       99.4 KB   121.5 KB   +22.1 KB   +22.2%  TOLERANS ASILDI
rota        37.3 KB    38.2 KB    +0.9 KB    +2.3%  -
bicem       30.9 KB    32.2 KB    +1.3 KB    +4.1%  -

yeni parcalar: rota-rapor.js (17.4 KB)
gerileme uyarisi:
  ortak: %22.2 buyume (tolerans %3)

cikis kodu: 1
```

Derleme dökümleri programın girdisidir; ölçülmüş bir projenin çıktısı değil, denetleyicinin
davranışını göstermek için yazılmış iki listedir.

## Çıktının Söyledikleri

Bütçe tanımındaki `toplama` alanı önemli bir ayrımı taşır. Giriş, ortak ve biçem grupları
için sınır **toplama** uygulanır: bu parçaların hepsi her sayfada yüklenir. Rota grubu için
sınır **en büyük tek parçaya** uygulanır, çünkü kullanıcı bir seferde tek bir rotayı
yükler. Yanlış toplama kuralı, yeni bir rota eklendiğinde bütçeyi haksız yere kırar.

Yeni derleme iki yerde kalıyor. Ortak parça kendi sınırını yüzde bir buçuk aşmış; toplam
ise sınırı yüzde beş aşmış. Toplamı aşan asıl neden ortak parçanın büyümesidir, ama yeni
eklenen rota parçası da toplama katkı yapar. İki satırın birlikte okunması, sorunun tek
bir değişiklikten mi yoksa birikimden mi geldiğini söyler.

Karşılaştırma tablosu bütçenin yakalayamadığını yakalıyor. Giriş parçası yüzde iki virgül
bir büyümüş ve sınırın hâlâ çok altında; uyarı üretmiyor. Ortak parça yüzde yirmi iki
büyümüş ve tolerans yüzde üç olduğu için uyarı üretiyor — bu parça sınırın altında kalsaydı
bile uyarı yine üretilirdi.

Ayrım budur. **Bütçe mutlak bir sınırı korur, tolerans değişim hızını korur.** Yalnız bütçe
denetlenirse, her yayında yüzde iki büyüyen bir paket aylarca sessiz kalır ve sınırı bir gün
aniden aşar; o gün hangi değişikliğin sorumlu olduğu artık bulunamaz.

Yeni parçaların ayrıca bildirilmesi de bu yüzdendir. İçerik karmalı adlar her yayında
değiştiği için karşılaştırma karma çıkarılarak yapılır; yoksa her parça yeni görünür.

## Bütçenin Yayın Hattındaki Yeri

Denetleyicinin çıkış kodu döndürmesi tasarımın parçasıdır: derleme sonrası çalışan
doğrulama adımlarında sıfırdan farklı bir çıkış kodu adımı durdurur. Kabuk Programlama
kursunda kurulan kural burada yaptırımın taşıyıcısıdır.

İki karar gerekir. **Nerede çalışacak?** Değişiklik başına çalışan bir denetim, sorunu
birleştirmeden önce bulur; yalnız ana dalda çalışan bir denetim, sorunu bulduğunda sorumlu
değişikliği aramak gerekir.

**Ne yapacak?** Bütçe aşımının derlemeyi durdurması ile uyarı üretmesi arasındaki seçim,
bütçenin ciddiyetini belirler. Durdurmayan bütçe hedefe dönüşür. Buna karşın bir kaçış
kapısı gerekir: sınırın bilinçli olarak yükseltilebilmesi ve yükseltmenin bir kayıt
bırakması. Bütçe dosyasında yapılan değişiklik incelemeye tabi olduğunda kaçış deliği da
denetlenmiş olur.

## Gürültü ve Yanlış Alarm

Nicelik bütçeleri belirlenimcidir; aynı girdiden aynı sayı çıkar. Ölçüt bütçeleri değildir
ve doğrudan uygulandıklarında yanlış alarm üretirler.

Üç önlem gerekir. Ölçüm **birden çok kez** yapılır ve ortanca alınır; tek bir koşu karar
için yeterli değildir. Ölçüm koşulları **sabitlenir**: aynı ağ kısıtlaması, aynı aygıt
profili, eklentisiz tarayıcı — Ağ Panelinde Tanı dersindeki yeniden üretilebilirlik
koşulları burada bütçenin ön şartıdır. Ve eşik, ölçümün doğal değişkenliğinden **belirgin
biçimde büyük** seçilir; gürültünün içinde kalan bir tolerans, sürekli kırmızı yanan ve bu
yüzden yok sayılan bir denetim üretir.

Bir de kapsam kararı vardır. Bütçe her sayfaya değil, temsilci sayfalara uygulanır:
istasyon listesi sayfası ve ölçüm ayrıntısı sayfası. İlk ders bu iki sayfanın farklı
ölçütlerle değerlendirildiğini göstermişti; bütçeleri de bu yüzden ayrı yazılır.

## Özet

- Bütçe, aşıldığında bir şeyin olduğu sınırdır; yaptırımı olmayan sayı hedeftir ve
  kötüleşmeyi durdurmaz.
- Üç bütçe türü birbirinin açığını kapatır: ölçüt bütçesi deneyimi ölçer ama gürültülüdür,
  nicelik bütçesi belirlenimcidir ama dolaylıdır, kural bütçesi sayıya inmeyen kararları
  korur.
- Bütçe grubunun toplama kuralı sonucu değiştirir: her sayfada yüklenen parçalar toplanır,
  seçenekli parçalarda en büyüğü ölçülür.
- Mutlak sınır ile büyüme toleransı ayrı şeyleri korur; yalnız sınır denetlendiğinde küçük
  ve düzenli büyümeler sınıra ulaşana kadar görünmez kalır.
- Ölçüt bütçeleri ancak ölçüm koşulları sabitlenip birden çok koşunun ortancası alındığında
  yaptırıma bağlanabilir.

## Sonraki Adım

Başarım artık bir görüş meselesi değil: tanımlı ölçütleri, yazılı sınırları ve her
derlemede çalışan bir denetimi var. Kalite ekseninin tamamı bu değildir. Bir sayfa hızlı
yüklenip yine de kullanılamaz olabilir — klavyeyle gezilemeyen bir liste, ekran okuyucuya
hiçbir şey söylemeyen bir düğme, karşıtlığı yetersiz bir metin. Bu sorunlar da bir görüş
meselesi olmak zorunda değildir; onların da tanımlı ölçütleri, ölçülebilir eşikleri ve
uygunluk düzeyleri vardır. Sonraki ders erişilebilirlik standartlarını ele alır ve
kullanılabilirliği aynı disiplinle — sınanabilir ölçütlerle — tanımlar.
