---
title: 'Yükleme ve Boş Durumlar'
source: 'https://academia.sh/tr/kurslar/arayuz-temelleri/yukleme-ve-bos-durumlar'
course: 'Arayüz Tasarımının Temelleri'
language: tr
updated: '2026-08-17T18:09:36+00:00'
license: 'CC BY-SA 4.0'
---

# Yükleme ve Boş Durumlar

Bekleme süresinin geri bildirim sınıflarına ayrılması, gösterge gecikmesinin titremeye etkisi, iskelet gösteriminin yerleşim kayması puanıyla gerekçelendirilmesi ve boş durumun üç türü.

Önceki ders bir bileşenin beş etkileşim durumunu tanımladı. Beşi de tek bir varsayıma
dayanıyordu: bileşen ekranda vardır ve etkileşime hazırdır. Katalog arayüzünde bu varsayım
sık sık geçersizdir. Kullanıcı arama düğmesine bastı ve sonuçlar henüz gelmedi; arama
hiçbir kayıt döndürmedi; ya da kullanıcı sayfayı yeni açtı ve hiç arama yapmadı.

Bu üç durumda ekranda gösterilecek bir sonuç listesi yoktur. Tasarlanacak şey listenin
kendisi değil, listenin **yokluğudur**. Bu ders yokluğun iki biçimini ayırır: veri yolda
olduğu için oluşan yokluk ve veri olmadığı için oluşan yokluk. İkisi farklı bilgi verir ve
farklı çözüm ister.

## Bekleme Bir Süre Aralığıdır

Yükleme durumu tek bir tasarım değildir; ne kadar sürdüğüne bağlı olarak farklı bir şey
gerektirir. Sürenin kendisi ölçülür ve karar ölçüme dayandırılır.

```js
// bekleme.mjs — olculen yanit surelerinin geri bildirim siniflarina dagitilmasi

// Yinelenebilir ornek uretimi: dogrusal esleyici uretec + log-normal donusum
function uretec(tohum) {
  let s = tohum >>> 0;
  return () => ((s = (1664525 * s + 1013904223) >>> 0) / 4294967296);
}
const rastgele = uretec(20260727);
function normal() {
  const u1 = Math.max(rastgele(), 1e-12), u2 = rastgele();
  return Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2);
}

// Katalog aramasinin yanit suresi (ms): medyani 220 ms, sag kuyruklu
const ornekler = Array.from({ length: 200 }, () =>
  Math.round(220 * Math.exp(0.9 * normal()))
).sort((a, b) => a - b);

const yuzdelik = (p) => ornekler[Math.min(ornekler.length - 1, Math.floor((p / 100) * ornekler.length))];
console.log(`ornek sayisi: ${ornekler.length}`);
console.log(`en kucuk ${ornekler[0]} ms   medyan ${yuzdelik(50)} ms   y90 ${yuzdelik(90)} ms   y99 ${yuzdelik(99)} ms   en buyuk ${ornekler[ornekler.length - 1]} ms`);

// Geri bildirim siniflari: her sinifin ust siniri ve gerektirdigi gosterim
const SINIFLAR = [
  { ad: "anlik",          ust: 100,    gosterim: "geri bildirim gerekmez" },
  { ad: "kesintisiz",     ust: 1000,   gosterim: "imlec/dugme durumu yeter" },
  { ad: "fark edilir",    ust: 10000,  gosterim: "yukleme gostergesi" },
  { ad: "uzun",           ust: Infinity, gosterim: "ilerleme + iptal" },
];

console.log("\nsinif        ust sinir(ms)  ornek sayisi  oran     gerekli gosterim");
for (const s of SINIFLAR) {
  const alt = SINIFLAR[SINIFLAR.indexOf(s) - 1]?.ust ?? 0;
  const n = ornekler.filter((v) => v > alt && v <= s.ust).length;
  console.log(
    `${s.ad.padEnd(12)} ${(s.ust === Infinity ? "-" : String(s.ust)).padStart(13)} ${String(n).padStart(13)}  ${(n / ornekler.length * 100).toFixed(1).padStart(5)}%   ${s.gosterim}`
  );
}

// Gosterge gecikmesi: gosterge kac istekte acilir, kacinda titreme uretir?
// Titreme olcutu: gosterge 200 ms'den kisa sure gorunur.
console.log("\ngecikme(ms)  gosterge acilan  titreyen  titreme orani (tum istekler)");
for (const gecikme of [0, 150, 300, 500]) {
  const acilan = ornekler.filter((v) => v > gecikme);
  const titreyen = acilan.filter((v) => v - gecikme < 200).length;
  console.log(
    `${String(gecikme).padStart(11)} ${String(acilan.length).padStart(16)} ${String(titreyen).padStart(9)} ${(titreyen / ornekler.length * 100).toFixed(1).padStart(28)}%`
  );
}

// En az gorunme suresi kurali: gosterge acildiysa en az 300 ms kalir.
// Bu, bazi isteklere yapay gecikme ekler; toplam maliyeti hesaplanir.
const GECIKME = 300, EN_AZ = 300;
let yapay = 0, etkilenen = 0;
for (const v of ornekler) {
  if (v <= GECIKME) continue;
  const gorunme = v - GECIKME;
  if (gorunme < EN_AZ) { yapay += EN_AZ - gorunme; etkilenen++; }
}
console.log(`\n300 ms gecikme + 300 ms en az gorunme:`);
console.log(`  yapay gecikme eklenen istek sayisi: ${etkilenen} / ${ornekler.length}`);
console.log(`  toplam eklenen sure: ${yapay} ms, istek basina ortalama: ${(yapay / ornekler.length).toFixed(1)} ms`);
```

```
ornek sayisi: 200
en kucuk 23 ms   medyan 228 ms   y90 722 ms   y99 2100 ms   en buyuk 2362 ms

sinif        ust sinir(ms)  ornek sayisi  oran     gerekli gosterim
anlik                  100            45   22.5%   geri bildirim gerekmez
kesintisiz            1000           147   73.5%   imlec/dugme durumu yeter
fark edilir          10000             8    4.0%   yukleme gostergesi
uzun                     -             0    0.0%   ilerleme + iptal

gecikme(ms)  gosterge acilan  titreyen  titreme orani (tum istekler)
          0              200        89                         44.5%
        150              126        59                         29.5%
        300               75        34                         17.0%
        500               41        20                         10.0%

300 ms gecikme + 300 ms en az gorunme:
  yapay gecikme eklenen istek sayisi: 47 / 200
  toplam eklenen sure: 7573 ms, istek basina ortalama: 37.9 ms
```

Sınıf sınırları insan algısıyla ilgili yerleşik eşiklerdir. Yüz milisaniyenin altındaki bir
yanıt anlık algılanır; bir saniyeye kadar olan yanıt akışı kesmez ama fark edilir; on
saniyeye kadar olan bekleme dikkatin dağılmasına yol açar; onun ötesi ise kullanıcının
başka bir işe geçtiği aralıktır.

Ölçüm bir tasarım kararını doğrudan veriyor: isteklerin yüzde 96'sı bir saniyenin altında
tamamlanıyor. Yani katalog aramasının **çoğunlukla** bir yükleme göstergesine ihtiyacı yok.
Gösterge her istekte açılırsa, gösterge kendisi bir gürültü kaynağı hâline gelir.

İkinci tablo bunu sayıya çeviriyor. Gösterge gecikmesiz açıldığında isteklerin yüzde 44.5'i
göstergenin 200 milisaniyeden kısa süre görünüp kaybolmasına yol açıyor; ekranda beliren ve
hemen kaybolan bir öge, bilgi vermek yerine dikkat çeker. Gecikme 300 milisaniyeye
çekildiğinde bu oran yüzde 17'ye, 500 milisaniyede yüzde 10'a iniyor.

Gecikme tek başına yetmez, çünkü gösterge açıldıktan hemen sonra da kapanabilir. İkinci
kural, gösterge bir kez açıldıysa en az bir süre görünür kalmasıdır. Üçüncü blok bunun
maliyetini veriyor: 300 milisaniyelik en az görünme kuralı 200 isteğin 47'sine yapay
gecikme ekliyor ve istek başına ortalama 37.9 milisaniye maliyet üretiyor. Bu maliyet
bilinçli ödenir: titremeyi ortadan kaldırmanın bedeli, bazı isteklerin biraz daha uzun
görünmesidir.

Üçüncü satırdaki "ilerleme + iptal" sınıfında hiç örnek yok. Bu, katalog aramasının o sınıfa
girmediği anlamına gelir; ancak arayüzün başka bir işlemi — toplu dışa aktarma gibi — o
sınıfa girerse ilerleme göstergesi ve iptal düğmesi zorunlu olur. Belirsiz bir gösterge, on
saniyeyi aşan işlemlerde kullanıcıya işlemin ilerleyip ilerlemediğini söylemez.

## İskelet Gösterimi Yer Ayırır

Yükleme göstergesinin ikinci işi, gelecek içeriğin yerini tutmaktır. Küçük bir dönen
gösterge bu işi yapmaz: içerik geldiğinde altındaki her şey aşağı itilir ve kullanıcının
baktığı nokta kayar.

Bu kayma ölçülebilir. **Yerleşim kayması puanı (layout shift score)**, kayan ögelerin
etkilediği alanın görüntü alanına oranı ile ögelerin kat ettiği uzaklığın görüntü alanının
en büyük kenarına oranının çarpımıdır.

```js
// iskelet.mjs — iskelet gosteriminin satir sayisi ve yerlesim kaymasi puani

const GORUNTU = { genislik: 1280, yukseklik: 800 };
const BASLIK_Y = 96;      // ust baslik seridi
const SATIR_Y = 72;       // sonuc satiri yuksekligi
const ALTLIK_Y = 80;      // altlik seridi

// 1) Gorunur alana kac iskelet satiri sigar?
const alan = GORUNTU.yukseklik - BASLIK_Y;
console.log(`gorunur icerik alani: ${alan} px`);
console.log(`satir yuksekligi: ${SATIR_Y} px`);
console.log(`tam sigan satir sayisi: ${Math.floor(alan / SATIR_Y)}`);
console.log(`kismen gorunen satir: ${(alan % SATIR_Y) > 0 ? "var (" + (alan % SATIR_Y) + " px)" : "yok"}`);

// 2) Yerlesim kaymasi puani: etki kesri x uzaklik kesri
// Kararsiz oge: altlik seridi. Yukleme gorunumunden yuklenmis gorunume gecerken kayar.
function kaymaPuani(oncekiUst, sonrakiUst) {
  const g = GORUNTU.yukseklik;
  const gorunurAralik = (ust) => {
    const alt = Math.min(g, ust + ALTLIK_Y);
    return ust >= g ? [0, 0] : [Math.max(0, ust), alt];
  };
  const [o1, o2] = gorunurAralik(oncekiUst);
  const [s1, s2] = gorunurAralik(sonrakiUst);
  const birlesimUst = Math.min(o1 || Infinity, s1 || Infinity);
  const birlesimAlt = Math.max(o2, s2);
  const etkiKesri = (birlesimAlt - birlesimUst) / g;
  const uzaklik = Math.abs(sonrakiUst - oncekiUst);
  const uzaklikKesri = uzaklik / Math.max(GORUNTU.genislik, GORUNTU.yukseklik);
  return { etkiKesri, uzaklikKesri, puan: etkiKesri * uzaklikKesri, uzaklik };
}

const SATIR_SAYISI = 9; // yuklenmis listede gorunur satir sayisi
const yuklenmisAltlik = BASLIK_Y + SATIR_SAYISI * SATIR_Y;

const SENARYOLAR = [
  { ad: "donen gosterge (120 px)", yukseklik: 120 },
  { ad: "iskelet 5 satir", yukseklik: 5 * SATIR_Y },
  { ad: "iskelet 8 satir", yukseklik: 8 * SATIR_Y },
  { ad: "iskelet 9 satir", yukseklik: SATIR_SAYISI * SATIR_Y },
];

console.log("\nyukleme gorunumu          altlik once  altlik sonra  uzaklik  etki kesri  uzaklik kesri  kayma puani");
for (const s of SENARYOLAR) {
  const once = BASLIK_Y + s.yukseklik;
  const k = kaymaPuani(once, yuklenmisAltlik);
  console.log(
    `${s.ad.padEnd(25)} ${String(once).padStart(11)} ${String(yuklenmisAltlik).padStart(13)} ${String(k.uzaklik).padStart(8)} ` +
      `${k.etkiKesri.toFixed(4).padStart(11)} ${k.uzaklikKesri.toFixed(4).padStart(14)} ${k.puan.toFixed(4).padStart(12)}`
  );
}
console.log("\niyi kabul edilen ust sinir: 0.100");
```

```
gorunur icerik alani: 704 px
satir yuksekligi: 72 px
tam sigan satir sayisi: 9
kismen gorunen satir: var (56 px)

yukleme gorunumu          altlik once  altlik sonra  uzaklik  etki kesri  uzaklik kesri  kayma puani
donen gosterge (120 px)           216           744      528      0.7300         0.4125       0.3011
iskelet 5 satir                   456           744      288      0.4300         0.2250       0.0968
iskelet 8 satir                   672           744       72      0.1600         0.0563       0.0090
iskelet 9 satir                   744           744        0      0.0700         0.0000       0.0000

iyi kabul edilen ust sinir: 0.100
```

Dönen gösterge 0.3011 puan üretiyor, iyi kabul edilen üst sınırın üç katı. Nedeni,
göstergenin gerçek içeriğe göre çok kısa olması ve içerik geldiğinde altlığın 528 piksel
aşağı itilmesidir.

İskelet gösteriminin satır sayısı bu puanı doğrudan belirliyor. Beş satır 0.0968 ile sınırın
hemen altında kalıyor, sekiz satır 0.0090'a iniyor, dokuz satırda kayma tümüyle ortadan
kalkıyor. Görünür alana tam olarak dokuz satır sığdığı için doğru sayı budur.

Buradan çıkan kural şudur: **iskelet, gelecek içeriğin sayısını değil, görünür alanın
alacağı satır sayısını taklit eder.** Arama otuz sonuç döndürecekse bile iskeletin otuz
satır çizmesi gereksizdir; görünür alandaki dokuz satır kaymayı sıfırlamaya yeter.

İskelet gösteriminin bir sınırı vardır ve gözden kaçırılır: iskelet, gelecek içeriğin
**yapısını** taahhüt eder. Dokuz satırlık bir iskelet çizilip ardından üç sonuç geldiğinde,
kullanıcı bir an için dokuz sonuç olduğunu sanmış olur. Bu yüzden iskelet yalnızca sonucun
geleceği kesin olduğunda kullanılır; sonuç sayısının sıfır olma olasılığı yüksek bir
aramada iskelet yerine yer tutan boş bir alan uygundur.

## Boş Durum Bir Hata Değildir

Yüklemenin bittiği ama içeriğin olmadığı durum, üç ayrı nedenden doğar ve üçü farklı şey
söyler.

**İlk kullanım boşluğu.** Kullanıcı katalog sayfasını yeni açtı ve henüz arama yapmadı.
Burada eksik olan veri değil, kullanıcının eylemi. Doğru içerik bir açıklama ve bir
başlangıç yoludur: aramanın neyi kapsadığı ve hangi alanlarda arama yapılabildiği.

**Sonuçsuz arama boşluğu.** Kullanıcı arama yaptı, sistem çalıştı, eşleşen kayıt yok.
Burada eksik olan veri. Doğru içerik, aramanın ne olduğunu tekrarlamak ve daraltmayı
gevşetecek bir yol sunmaktır: uygulanan filtrelerin listesi ve tek tek kaldırma seçeneği.
Arama metnini tekrarlamak bir ayrıntı değil, gerekliliktir; kullanıcının yazdığını
yanlış yazdığını görmesinin tek yolu odur.

**Temizlenmiş liste boşluğu.** Kullanıcı ödünç aldığı bütün kitapları iade etti ve "ödünç
aldıklarım" listesi boşaldı. Burada boşluk bir başarıdır. Doğru içerik ne açıklama ne
öneridir; durumu bildiren tek bir satır yeterlidir.

Üç durumun ortak yanlışı, boşluğu bir hata gibi sunmaktır. Hata rengi, uyarı simgesi ve
"bulunamadı" ifadesi kullanıcıya bir şeyin bozulduğunu söyler; oysa üç durumda da sistem
doğru çalışmıştır. İşlevsel Renkler dersindeki ayrım burada uygulanır: boş durum bilgi
sınıfına girer, hata sınıfına değil.

Boş durumun ikinci yaygın yanlışı, ekranı tümüyle boş bırakmaktır. Kullanıcı bu durumda
yüklemenin sürüp sürmediğini bilemez. Boş durum da bir tasarımdır ve bir metin taşımak
zorundadır; hangi metnin nasıl yazılacağı bu konunun son dersinin sorusudur.

## Özet

- Bekleme tek bir durum değil, süreye göre farklı gösterim isteyen bir aralıktır; sınıf
  sınırları ölçülen sürelerle karşılaştırılır.
- Ölçüm çoğu isteğin gösterge eşiğinin altında tamamlandığını gösterirse, gösterge
  gecikmeli açılır; gecikme titreme oranını doğrudan düşürür.
- Gösterge açıldıktan sonra en az bir süre görünür kalır; bunun bedeli bazı isteklere
  eklenen yapay gecikmedir ve bu bedel hesaplanabilir.
- İskelet gösterimi yer ayırarak yerleşim kaymasını sıfırlar; doğru satır sayısı gelecek
  sonuç sayısı değil, görünür alana sığan satır sayısıdır.
- İskelet gelecek içeriğin yapısını taahhüt eder; sonuç gelmeme olasılığı yüksekse iskelet
  yanıltıcıdır.
- Boş durum üç ayrı nedenden doğar ve hiçbiri hata değildir; boşluk bilgi sınıfında sunulur
  ve her zaman bir metin taşır.

## Sonraki Adım

Boş durum sistemin doğru çalıştığı bir sonuçtu. Sistemin doğru çalışmadığı durumlar ise
ayrı bir tasarım gerektirir: ISBN alanına geçersiz bir değer girildi, ödünç alma isteği
sunucuya ulaşamadı, kullanıcının ödünç alma hakkı doldu. Bu üçü aynı kutuda sunulamaz,
çünkü üçünün de kurtarma yolu farklıdır. Sonraki ders hatayı kaynağına ve kurtarılabilirliğine
göre sınıflandırır, iletinin nereye konacağını hata alanına olan uzaklıkla belirler ve
hangi hataların hiç gösterilmemesi gerektiğini tartışır.
