---
title: 'Çalışma Zamanı Başarımı'
source: 'https://academia.sh/tr/kurslar/frontend-kalitesi/calisma-zamani-basarimi'
course: 'Frontend Kalitesi'
language: tr
updated: '2026-08-17T18:09:22+00:00'
license: 'CC BY-SA 4.0'
---

# Çalışma Zamanı Başarımı

Ana iş parçacığındaki uzun görevlerin toplam engelleme süresiyle ölçülmesi, işin bölüntülenmesinin ölçülen etkisi, yerleşim sarsıntısının satır sayısıyla ölçeklenmesi ve görünmeyeni çizmemenin yolları.

Ağ tarafı düzenlendiğinde baytlar zamanında gelir ve tekrar ziyaret neredeyse istek
yapmaz. Uygulama yine de ağır hissettirebilir: istasyon listesi kaydırılırken takılıyor,
süzgeç kutusuna yazılan harf ekranda geç görünüyor, tarih aralığı değiştirildiğinde sayfa
bir an donuyor olabilir.

Bu sorunların hiçbiri ağda değildir. Hepsi indirilmiş kodun tek bir sırada çalışmasından
doğar. Tarayıcı ve Web Platformu kursundaki Başarım Kaydı dersi bu sırayı görünür kılan
aracı ele almıştı; bu ders sıranın nasıl boşaltılacağını ele alır.

## Uzun Görev ve Toplam Engelleme Süresi

Ana iş parçacığı bir görev sırasıdır. Bir görev başladıktan sonra bölünemez: sürdüğü sürece
kullanıcı girdisi işlenemez, kare üretilemez. Elli milisaniyeyi aşan görevler **uzun görev**
sayılır ve eşiğin gerekçesi girdi yanıtıdır.

Ölçüt, uzun görevlerin sayısı değil, eşiği aşan bölümlerinin toplamıdır.

```js
// engelleme.mjs — toplam engelleme suresi ve ayni isin bolunmus hali

const UZUN_GOREV = 50; // ms

const gorevler = [
  { ad: "belge ayristirma", sure: 42 },
  { ad: "paket degerlendirme", sure: 186 },
  { ad: "istasyon listesi olusturma", sure: 128 },
  { ad: "olcum bicimleme", sure: 61 },
  { ad: "girdi isleyicisi", sure: 18 },
  { ad: "kaydirma isleyicisi", sure: 33 },
];

console.log("gorev".padEnd(28) + "sure".padStart(8) + "engelleyen".padStart(12));
let toplamEngelleme = 0;
for (const g of gorevler) {
  const engelleyen = Math.max(0, g.sure - UZUN_GOREV);
  toplamEngelleme += engelleyen;
  console.log(g.ad.padEnd(28) + `${g.sure} ms`.padStart(8) + `${engelleyen} ms`.padStart(12));
}
console.log("-".repeat(48));
console.log("toplam engelleme suresi".padEnd(28) + `${toplamEngelleme} ms`.padStart(20));

// Ayni is, 50 ms'yi asmayan parcalara bolunurse engelleme sifira iner.
const bolunmus = gorevler.flatMap((g) => {
  const parca = Math.ceil(g.sure / UZUN_GOREV);
  return Array.from({ length: parca }, () => g.sure / parca);
});
const bolunmusEngelleme = bolunmus.reduce((t, s) => t + Math.max(0, s - UZUN_GOREV), 0);
console.log(`ayni is ${bolunmus.length} parcaya bolunurse: ${bolunmusEngelleme} ms engelleme`);
console.log(`toplam is suresi degismedi: ${gorevler.reduce((t, g) => t + g.sure, 0)} ms`);
```

```
gorev                           sure  engelleyen
belge ayristirma               42 ms        0 ms
paket degerlendirme           186 ms      136 ms
istasyon listesi olusturma    128 ms       78 ms
olcum bicimleme                61 ms       11 ms
girdi isleyicisi               18 ms        0 ms
kaydirma isleyicisi            33 ms        0 ms
------------------------------------------------
toplam engelleme suresi                   225 ms
ayni is 12 parcaya bolunurse: 0 ms engelleme
toplam is suresi degismedi: 468 ms
```

Görev süreleri hesabın girdisidir; hesaplanan şey ölçütün kendisidir. Dört yüz altmış sekiz
milisaniyelik işin iki yüz yirmi beş milisaniyesi engelleyicidir. Kırk iki milisaniyelik
ayrıştırma hiç sayılmaz, çünkü eşiğin altındadır — ölçüt işin tamamını değil, kullanıcının
yanıt bekleyeceği fazlalığı ölçer.

Son iki satır kritik olanı söylüyor: aynı iş elli milisaniyeyi aşmayan parçalara
bölündüğünde engelleme sıfıra iner ve toplam iş süresi hiç değişmez. Yapılan şey işi
azaltmak değil, **araya çıkış noktaları koymaktır.**

## Bölüntülemenin Ölçülmesi

Modelin söylediği şey ölçülebilir. Aşağıdaki program aynı işi üç yazımla yapar ve her
birinde olay döngüsünün ne kadar süreyle bloke olduğunu bir yoklayıcıyla kaydeder.

```js
// boluntule.mjs — ayni isin tek parcada ve boluntulenmis olarak olculmesi
// Yanit yoklayicisi: her turda kendini yeniden kurar, gecikmesini kaydeder.
function yoklayiciBaslat(kayit) {
  let calisiyor = true;
  let onceki = performance.now();
  const tur = () => {
    if (!calisiyor) return;
    const simdi = performance.now();
    kayit.push(simdi - onceki);
    onceki = simdi;
    setTimeout(tur, 0);
  };
  setTimeout(tur, 0);
  return () => { calisiyor = false; };
}

const SATIR = 300_000;
function satirMetni(i) {
  // Her satir icin bir miktar is: bicimlenmis bir olcum satiri uretmek.
  const sicaklik = -12 + ((i * 37) % 240) / 10;
  const zaman = new Date(Date.UTC(2026, 0, 1, 0, 0, i % 60)).toISOString();
  return `kuzey-yamac-${String(i).padStart(5, "0")} ${zaman} ${sicaklik.toFixed(1)} C`.length;
}

async function tekParcada() {
  let toplam = 0;
  for (let i = 0; i < SATIR; i++) toplam += satirMetni(i);
  return toplam;
}

async function boluntulenmis(parcaBoyu) {
  let toplam = 0;
  for (let i = 0; i < SATIR; i++) {
    toplam += satirMetni(i);
    if ((i + 1) % parcaBoyu === 0) await new Promise((coz) => setImmediate(coz));
  }
  return toplam;
}

async function olc(ad, is) {
  const gecikmeler = [];
  const durdur = yoklayiciBaslat(gecikmeler);
  await new Promise((coz) => setTimeout(coz, 20)); // yoklayici isinsin
  gecikmeler.length = 0;
  const bas = performance.now();
  const sonuc = await is();
  const gecen = performance.now() - bas;
  await new Promise((coz) => setTimeout(coz, 20)); // son yoklama kaydedilsin
  durdur();
  const enBuyuk = Math.max(...gecikmeler);
  return { ad, gecen, enBuyuk, sonuc, tur: gecikmeler.length };
}

const olcumler = [
  await olc("tek parcada", tekParcada),
  await olc("2000 satirlik parcalar", () => boluntulenmis(2000)),
  await olc("500 satirlik parcalar", () => boluntulenmis(500)),
];

console.log("--- ayni is, farkli boluntuleme (sureler ortama baglidir) ---");
console.log("yaklasim".padEnd(24) + "toplam".padStart(10) + "en uzun engelleme".padStart(19) +
  "yoklama".padStart(9));
for (const o of olcumler) {
  console.log(o.ad.padEnd(24) + `${o.gecen.toFixed(1)} ms`.padStart(10) +
    `${o.enBuyuk.toFixed(1)} ms`.padStart(19) + String(o.tur).padStart(9));
}
const taban = olcumler[0];
console.log("\nen uzun engellemenin tek parcaya orani:");
for (const o of olcumler) {
  console.log(`  ${o.ad.padEnd(24)} ${(o.enBuyuk / taban.enBuyuk).toFixed(3)}`);
}
console.log(`butun yaklasimlar ayni sonucu uretti: ${new Set(olcumler.map((o) => o.sonuc)).size === 1}`);
```

```
--- ayni is, farkli boluntuleme (sureler ortama baglidir) ---
yaklasim                    toplam  en uzun engelleme  yoklama
tek parcada               126.9 ms           128.2 ms       18
2000 satirlik parcalar    128.5 ms             2.3 ms      144
500 satirlik parcalar     135.5 ms             1.9 ms      152

en uzun engellemenin tek parcaya orani:
  tek parcada              1.000
  2000 satirlik parcalar   0.018
  500 satirlik parcalar    0.015
butun yaklasimlar ayni sonucu uretti: true
```

Süreler makineye ve yüke bağlıdır; her çalıştırmada değişirler. Değişmeyen şey oranlardır.
Toplam süre üç yazımda birbirine yakın kalır — bölüntüleme işi azaltmaz, hatta tur başına
küçük bir ek yük getirir. En uzun engelleme ise iki mertebe düşer: yüz yirmi sekiz
milisaniyelik tek blok, iki milisaniyenin altındaki bloklara dağılır.

Yoklama sayısı bunun nedenini gösterir. Tek parçalı yazımda iş sürerken sıraya hiç
dönülmez; bölüntülenmiş yazımda her parçadan sonra dönülür ve bekleyen girdi işlenebilir.

Bu ölçüm bir tarayıcıda değil, tek iş parçacıklı bir çalışma zamanında yapılmıştır; ana iş
parçacığının davranışını doğru modeller, ama tarayıcıdaki çıkış noktası `setImmediate`
değildir. Tarayıcıda karşılığı, denetimi olay döngüsüne bırakan bir bekleme ya da boşta
çalışma çağrısıdır.

Bölüntülemenin bir de sınırı vardır: parça küçüldükçe tur başına ek yük büyür. Beş yüz
satırlık parçalarda toplam süre iki bin satırlık parçalardan yüksektir. Doğru parça boyu
"olabildiğince küçük" değil, kare bütçesine sığan en büyük parçadır.

## İşi Sıradan Tümüyle Çıkarmak

Bölüntüleme işi ana sırada tutar ve araya girmeye izin verir. İkinci bir yol, işi sıradan
tümüyle çıkarmaktır.

Tarayıcı ve Web Platformu kursunda tanıtılan çalışanlar ayrı bir iş parçacığında koşar ve
ana sırayı hiç meşgul etmez. Uygun olduğu işler bellidir: saf hesap, ayrıştırma,
sıkıştırma, büyük veri kümesinin süzülmesi ve sıralanması. Uygun olmadığı iş de bellidir —
belge ağacına erişim. Ölçüm ayrıntısı sayfasında on binlerce ölçümün özetlenmesi çalışana
taşınabilir; sonuç ana sıraya yalnızca çizilecek satırlar olarak döner.

Bedeli veri aktarımıdır. İleti geçişi kopyalama gerektirir ve büyük dizilerde bu kopyalama
kazancı yiyebilir; aktarılabilir nesneler bunun için vardır.

## Yerleşim Sarsıntısı Satır Sayısıyla Ölçeklenir

Düzen Sistemleri ve Duyarlı Tasarım kursundaki Animasyon Başarımı dersi zorlanmış yerleşim
hesabını tanımlamıştı: bir yazma işlemi yerleşimi geçersiz kılar, sonraki bir ölçü okuması
hesabı hemen zorlar. Okuma ile yazmanın sıralanması bu hesabı her turda tekrarlar ve buna
**yerleşim sarsıntısı** denir.

Orada sayılan şey hesap adediydi. Buradaki soru, adedin liste büyüdükçe ne olduğudur.

```js
// sarsinti.mjs — yerlesim sarsintisinin satir sayisiyla nasil olcekledigi

const KARE_BUTCESI = 1000 / 60; // ms, saniyede 60 kare varsayimiyla
const HESAP_MALIYETI = 0.05;    // ms: tek bir yerlesim hesabinin varsayilan maliyeti
const GORUNUR_SATIR = 20;       // gorunum alanina sigan satir sayisi

// Uc yaklasim: her biri N satir icin kac yerlesim hesabi zorlar?
const yaklasimlar = {
  "dongu icinde oku-yaz": (n) => Math.max(0, n - 1),
  "okumalar sonra yazmalar": () => 0,
  "yalniz gorunur satirlar": (n) => Math.max(0, Math.min(n, GORUNUR_SATIR) - 1),
};

console.log("satir".padStart(7) +
  Object.keys(yaklasimlar).map((a) => a.padStart(26)).join(""));
for (const n of [10, 50, 200, 1000, 5000]) {
  const hucreler = Object.values(yaklasimlar).map((f) => {
    const hesap = f(n);
    const sure = hesap * HESAP_MALIYETI;
    return `${hesap} hesap / ${sure.toFixed(1)} ms`.padStart(26);
  });
  console.log(String(n).padStart(7) + hucreler.join(""));
}

console.log(`\nkare butcesi: ${KARE_BUTCESI.toFixed(2)} ms`);
console.log("kac kare butcesi tuketilir:");
console.log("satir".padStart(7) +
  Object.keys(yaklasimlar).map((a) => a.padStart(26)).join(""));
for (const n of [10, 50, 200, 1000, 5000]) {
  const hucreler = Object.values(yaklasimlar).map((f) =>
    (f(n) * HESAP_MALIYETI / KARE_BUTCESI).toFixed(1).padStart(26));
  console.log(String(n).padStart(7) + hucreler.join(""));
}

console.log("\nhesap maliyeti bir varsayimdir; degistiginde sutunlarin orani degismez.");
```

```
  satir      dongu icinde oku-yaz   okumalar sonra yazmalar   yalniz gorunur satirlar
     10          9 hesap / 0.5 ms          0 hesap / 0.0 ms          9 hesap / 0.5 ms
     50         49 hesap / 2.5 ms          0 hesap / 0.0 ms         19 hesap / 1.0 ms
    200       199 hesap / 10.0 ms          0 hesap / 0.0 ms         19 hesap / 1.0 ms
   1000       999 hesap / 50.0 ms          0 hesap / 0.0 ms         19 hesap / 1.0 ms
   5000     4999 hesap / 250.0 ms          0 hesap / 0.0 ms         19 hesap / 1.0 ms

kare butcesi: 16.67 ms
kac kare butcesi tuketilir:
  satir      dongu icinde oku-yaz   okumalar sonra yazmalar   yalniz gorunur satirlar
     10                       0.0                       0.0                       0.0
     50                       0.1                       0.0                       0.1
    200                       0.6                       0.0                       0.1
   1000                       3.0                       0.0                       0.1
   5000                      15.0                       0.0                       0.1

hesap maliyeti bir varsayimdir; degistiginde sutunlarin orani degismez.
```

On satırlık bir listede üç yaklaşım arasında fark yoktur; sorun bu yüzden geliştirme
sırasında görünmez. Beş bin satırda ilk yaklaşım on beş kare bütçesi tüketir, yani çeyrek
saniye boyunca hiçbir kare üretilmez.

İki çözümün karakteri farklıdır. Okumaları ve yazmaları öbeklemek maliyeti **sıfıra**
indirir ve liste büyüklüğünden bağımsızdır; yalnızca görünür satırları işlemek maliyeti
**sabitler** ve liste ne kadar büyürse büyüsün değişmez. İkincisi, sarsıntıyı olduğu gibi
bırakır ama ölçeklenmesini keser.

## Görünmeyeni Çizmemek

Görünür olanı işlemek fikri yerleşim sarsıntısıyla sınırlı değildir; tarayıcının çizim
hattının tamamı için geçerlidir.

**Sanallaştırma** listenin yalnızca görünen bölümünü belge ağacına koyar. Kaydırıldıkça
düğümler yeniden kullanılır. Bedeli, ağaçta bulunmayan içeriğin sayfa içi aramada ve
erişilebilirlik ağacında da bulunmamasıdır.

**İçerik görünürlüğü bildirimi** aynı hedefe işaretlemeyi bozmadan yaklaşır: `content-visibility`
özelliği bir kutunun ekran dışındayken çizim ve yerleşim işlerinin atlanmasını sağlar.
Atlanan işin kutusu yine de bir yer kaplamalıdır; yoksa kaydırma çubuğu içerik göründükçe
zıplar. Bu yüzden bildirimle birlikte tahmini bir boyut verilir.

**Sınırlama** bildirimi ise bir kutunun etkisini kendi sınırlarında tutar. Animasyon
Başarımı dersinde tanıtılan `contain` bildirimi, bir kart içindeki değişikliğin yerleşim
hesabını sayfanın tamamına yaymasını önler.

## Etkileşim Gecikmesinin Üç Bileşeni

Sonraki boyaya etkileşim tek bir sayıdır ama üç ayrı gecikmenin toplamıdır ve düzeltmeleri
farklıdır.

**Girdi gecikmesi**, kullanıcı etkileşimi ile işleyicinin başlaması arasındaki süredir.
Nedeni, o sırada süren başka bir görevdir. Çözümü bölüntüleme ya da işi çalışana taşımaktır;
işleyiciyi hızlandırmak bu bölüme dokunmaz.

**İşleme süresi**, işleyicilerin kendi süresidir. Çözümü işleyicinin küçültülmesi ve
ertelenebilir işin ertelenmesidir: kullanıcının gördüğü değişikliği hemen yap, kaydı ve
istatistiği sonraya bırak.

**Sunum gecikmesi**, işleyici bittikten sonra karenin üretilmesine kadar geçen süredir.
Nedeni işleyicinin tetiklediği yerleşim ve boyama işinin büyüklüğüdür. Çözümü, güncellenen
alanı küçültmektir.

Kaydın hangi bileşenin büyüdüğünü göstermesi, hangi düzeltmenin denenmeyeceğini de söyler.
Ölçmeden yapılan eniyileme çoğu zaman yanlış bileşene uygulanır.

## Özet

- Toplam engelleme süresi, uzun görevlerin elli milisaniyelik eşiği aşan bölümlerinin
  toplamıdır; işi bölüntülemek toplam süreyi değiştirmeden bu ölçütü sıfıra indirebilir.
- Ölçüm bunu doğrular: aynı iş bölüntülendiğinde en uzun engelleme iki mertebe düşer, toplam
  süre yakın kalır; parça küçüldükçe tur başına ek yük artar.
- Çalışanlar işi ana sıradan tümüyle çıkarır; sınırları belge ağacına erişememek ve veri
  kopyalama maliyetidir.
- Yerleşim sarsıntısının maliyeti satır sayısıyla doğrusal büyür; öbekleme maliyeti sıfıra
  indirir, görünür satırlarla çalışmak sabitler.
- Sonraki boyaya etkileşim girdi gecikmesi, işleme süresi ve sunum gecikmesinin toplamıdır
  ve her bileşenin düzeltmesi ayrıdır.

## Sonraki Adım

Beş derste ölçütler tanımlandı, kritik yol kısaltıldı, varlıklar boyutlandırıldı, ağ
katmanı ayarlandı ve çalışma zamanı boşaltıldı. Bütün bunların ortak açığı şudur: hepsi bir
kez yapılmış iyileştirmelerdir. Yeni bir özellik eklendiğinde paket büyür, yeni bir görsel
konduğunda ilk ekranın ağırlığı artar, bir kütüphane ortak parçaya girdiğinde tekrar
ziyaret kazancı erir. Bu erimenin bir sonraki yayında fark edilmesi gerekir, aylar sonra
şikâyetle değil. Sonraki ders ölçütleri yazılı bir bütçeye bağlar ve iki derleme çıktısını
karşılaştırarak gerilemeyi yakalayan bir denetleyici kurar.
