İçeriğe geç
academia.sh

Ders 02 / 25

Tarayıcının Görevleri

Gelen baytların karakterlere, karakterlerin sözcük birimlerine, birimlerin ağaca ve ağacın ekrandaki kutulara dönüşmesi; her aşamanın girdisi ve çıktısı.

İçindekiler

Önceki ders işaretlemenin bir bildirim katmanı olduğunu kurdu ve belgenin okunacak metinle onu niteleyen yapıdan oluştuğunu gösterdi. Geriye tarayıcının bu bildirimle ne yaptığı sorusu kaldı.

İnternet Nasıl Çalışır kursundaki Tarayıcı Ne Yapar dersi, adresin çözümlenmesinden bağlantı kurmaya ve alt kaynakların istenmesine kadar olan zinciri anlatmıştı. Bu ders o zincirin bir halkasını açar: yanıt gövdesi geldikten sonra ne olduğunu. Aşamalar birbirine girdi–çıktı ilişkisiyle bağlıdır ve her birinin çıktısı, bir sonrakinin dilinde yazılmıştır.

Aşamaların Zinciri

Belge geldiğinde altı dönüşüm sırayla uygulanır.

Aşama Girdi Çıktı
Kod çözme bayt dizisi karakter dizisi
Sözcüksel çözümleme karakter dizisi sözcük birimi akışı
Ağaç kurma sözcük birimi akışı düğüm ağacı
Biçem çözümleme düğüm ağacı + biçem kuralları biçemli ağaç
Yerleşim biçemli ağaç kutuların konum ve boyutları
Boyama kutular piksel

Zincirin her halkası ayrı bir sorumluluk taşır. Sözcüksel çözümleyici bir ögenin nereye ait olduğunu bilmez; ağaç kurucu karakter kodlamasını bilmez; yerleşim, sözcük birimlerinin ne olduğunu bilmez. Bu ayrım, aşamalardan birinin bağımsız olarak değiştirilmesine izin verir.

Kod Çözme: Bayttan Karaktere

Ağdan gelen şey bayttır. Bilgisayarlar Nasıl Çalışır kursundaki Karakter Kodlamaları dersinde kurulduğu üzere, bayt dizisinin karakter dizisine çevrilmesi bir kural gerektirir; baytların kendisi hangi kuralla yazıldığını söylemez.

// birimler.mjs — bayt dizisinden birim akışına
const baytlar = Buffer.from('<p class="olcum">Sıcaklık: <b>-4</b> derece</p>', "utf8");
console.log("bayt sayisi     :", baytlar.length);

const metin = baytlar.toString("utf8"); // charset bildirimi bu adimi belirler
console.log("karakter sayisi :", metin.length);
console.log("--- birimler ---");

let i = 0;
while (i < metin.length) {
  const k = metin.indexOf("<", i);
  if (k === -1) { console.log("METIN   ", JSON.stringify(metin.slice(i))); break; }
  if (k > i) console.log("METIN   ", JSON.stringify(metin.slice(i, k)));
  const son = metin.indexOf(">", k);
  const ic = metin.slice(k + 1, son);
  if (ic.startsWith("/")) {
    console.log("KAPANIS  " + ic.slice(1));
  } else {
    const bosluk = ic.search(/[\s/]/);
    const ad = bosluk === -1 ? ic : ic.slice(0, bosluk);
    const kalan = bosluk === -1 ? "" : ic.slice(bosluk).trim();
    console.log("ACILIS   " + ad + (kalan ? "  [" + kalan + "]" : ""));
  }
  i = son + 1;
}
bayt sayisi     : 49
karakter sayisi : 47
--- birimler ---
ACILIS   p  [class="olcum"]
METIN    "Sıcaklık: "
ACILIS   b
METIN    "-4"
KAPANIS  b
METIN    " derece"
KAPANIS  p

İlk iki satır, kod çözme aşamasının neden ayrı bir aşama olduğunu gösterir: 49 bayt, 47 karaktere karşılık gelir. Fark, ı ve ç karakterlerinin bu kodlamada birer değil ikişer bayt tutmasından gelir. Bayt sayısıyla karakter sayısı arasındaki bu ayrım, belgenin uzunluğu üzerine kurulan her hesapta önem taşır.

Kod çözmenin hangi kurala göre yapılacağı belgenin kendi içinde bildirilir. Bu bildirimin biçimini ve nasıl bir sıra izlendiğini Meta Etiketleri dersinde ele alacağız.

Sözcüksel Çözümleme: Karakterden Sözcük Birimine

Yukarıdaki çıktının ikinci bölümü bu aşamanın ürünüdür. Aşamanın ürettiği birimin adı sözcük birimidir (token); kavram, Bilgisayarlar Nasıl Çalışır kursundaki Derleme Aşamaları dersinde aynı adla tanımlanmıştı. Çözümleyici karakter dizisini soldan sağa okur ve üç tür birim üretir: açılış etiketi, kapanış etiketi ve metin. Yorum ve belge türü bildirimi için de ayrı birim türleri vardır.

Çözümleyicinin yapmadığı şey dikkate değerdir. b ögesinin p ögesinin içinde olduğunu söylemez; yalnızca birimlerin sırasını verir. İç içelik bilgisi, sıradan üretilecek olan bir sonuçtur; birimin kendisinde yoktur. Aynı biçimde çözümleyici p ögesinin kapanmamış olmasını da sorun saymaz: kapanış birimi gelmezse üretmez, o kadar.

Çözümleyici bir durum makinesidir (state machine): hangi karakteri nasıl yorumlayacağı o an bulunduğu duruma bağlıdır. Metin durumundayken < karakteri etiket başlangıcı sayılır; etiket adı durumundayken boşluk, adın bittiğini bildirir; öznitelik değeri durumundayken tırnak içinde < karakteri sıradan bir karakterdir. Bu nedenle “HTML’i düzenli ifadeyle ayrıştırmak” genel durumda doğru sonuç vermez: düzenli ifadeler durumdan duruma geçen bu davranışı kuramaz. Yukarıdaki betik ancak örnek kadar dar bir girdide doğru çalışır.

Ağaç Kurma

Sözcük birimi akışı sıralı ve düzdür; belge ise iç içedir. Ağaç kurucu, açılış birimlerini bir yığıta koyarak ve kapanış birimlerinde yığıttan çıkararak bu iç içeliği kurar. Ayrıntısı sonraki dersin konusudur.

Biçem Çözümleme ve Kutu Üretimi

Ağaç kurulduğunda hangi ögenin ne olduğu bilinir ama nasıl görüneceği bilinmez. Biçem çözümleme aşaması her ögeye uygulanacak biçem değerlerini hesaplar. Bu değerlerin bir bölümü belgeye dışarıdan bağlanan kurallardan, bir bölümü tarayıcının kendi varsayılan kurallarından gelir.

Varsayılan biçemlerin varlığı önemlidir: hiçbir biçem dosyası bağlanmamış bir belge de yapılı görünür — başlıklar büyük ve kalın, listeler girintili, bağlantılar ayırt edilebilir olur. Bu görünüm ögelerin doğasından değil, tarayıcının her öge için taşıdığı varsayılan kural kümesinden gelir. Ögeleri “kalın olan” veya “girintili olan” diye anmak bu yüzden yanıltıcıdır; bunlar sunum katmanının varsayılanlarıdır ve değiştirilebilir.

Biçem hesabının çıktısı, her görünür öge için bir kutudur. Kutunun türü ögenin biçem değerine bağlıdır: kimi kutular satır boyunca yayılır, kimi kutular metnin içinde akar. Bazı ögeler hiç kutu üretmez; head bölümündeki içerik ve gizlenmiş ögeler bu durumdadır.

Yerleşim ve Boyama

Yerleşim (layout), kutuların birbirine göre yerini ve ölçüsünü hesaplar. Bu hesap kullanılabilir genişlikten başlar ve ağaçta aşağı doğru ilerler: her kutu, kendisine ayrılan alanı bilir ve çocuklarına dağıtır. Çıktı, her kutu için bir konum ve bir boyuttur.

Boyama (paint), hesaplanmış kutuları renklere çevirir. Arka planlar, kenarlıklar, metin ve görseller sırayla çizilir. Çizim sırası, ögelerin belgede görünme sırasından ayrıdır: bir ögenin başka bir ögenin üstünde görünmesi biçem katmanının kararıdır.

İki aşamanın ayrılması, yeniden çalışma maliyetini de ayırır. Bir ögenin rengi değiştiğinde yalnızca boyama yinelenir; genişliği değiştiğinde yerleşim de yinelenir ve yerleşim, değişen kutunun komşularını ve çocuklarını da etkilediği için daha pahalıdır. Bu ayrım, sonraki kurslarda başarım konusunun dayanağıdır.

Kutular Ögelerle Bire Bir Örtüşmez

Belgedeki öge sayısıyla ekrandaki kutu sayısı eşit değildir ve bu, yerleşim aşamasının ayrı bir aşama olmasının gerekçesidir. Üç sapma vardır.

Bir öge hiç kutu üretmeyebilir. head bölümünün içeriği, yorum düğümleri ve sunum katmanınca gizlenmiş ögeler yerleşime girmez. Bu ögeler ağaçta durur, sorgulanabilir ve betiklerce değiştirilebilir; yalnızca çizilmezler.

Bir öge birden çok kutu üretebilir. İki satıra sığan bir paragrafın metni iki satır kutusuna bölünür; bir bağlantının metni satır sonuna denk gelirse iki parçaya ayrılır ve her parçanın kendi konumu ve ölçüsü olur. Ögenin kendisi tektir, kutusu değildir.

Bir kutu hiçbir ögeye karşılık gelmeyebilir. Sunum katmanı, belgede bulunmayan içerik üretebilir; liste imleri ve üretilmiş içerik bu türdendir. Bu kutular ağaçta bir düğüme karşılık gelmez.

Bu üç sapma, “belgeyi değiştirmek” ile “görünümü değiştirmek” arasındaki farkı somutlaştırır. Ağaç, belgenin anlamını taşır; kutular, o anlamın belirli bir genişlikte, belirli bir biçemle aldığı görünümdür.

Aşamalar Örtüşür

Zincir, birinci aşama tamamen bitmeden ikincisi başlamayacak biçimde işlemez. Belgenin tamamı gelmeden ayrıştırma başlar; ağacın bir bölümü kurulduğunda ilk yerleşim hesabı yapılabilir ve ilk boyama gerçekleşebilir. Kullanıcının uzun bir belgede ilk ekranı belgenin tamamı inmeden görmesi bu örtüşmenin sonucudur.

Örtüşmenin bozulduğu yerler vardır: bazı kaynaklar ayrıştırmayı durdurur, bazıları boyamayı bekletir. Bu, konunun dördüncü dersinin konusudur.

Özet

  • Belge, art arda altı dönüşümden geçer: kod çözme, sözcüksel çözümleme, ağaç kurma, biçem çözümleme, yerleşim, boyama. Her aşamanın çıktısı bir sonrakinin girdisidir.
  • Kod çözme aşaması bayt dizisini karakter dizisine çevirir; bayt sayısıyla karakter sayısı eşit değildir ve çevirinin kuralı belgede bildirilir.
  • Sözcüksel çözümleyici bir durum makinesidir ve yalnızca sıra üretir; iç içelik bilgisini taşımaz. Bu nedenle işaretleme genel durumda düzenli ifadeyle ayrıştırılamaz.
  • Ögelerin varsayılan görünümü doğalarından değil, tarayıcının varsayılan biçem kurallarından gelir.
  • Yerleşim kutuların yerini ve ölçüsünü, boyama görünümünü hesaplar; bir değişikliğin hangi aşamayı yeniden çalıştırdığı maliyeti belirler.
  • Aşamalar örtüşür: belgenin tamamı gelmeden ayrıştırma, ağacın tamamı kurulmadan çizim başlayabilir.

Sonraki Adım

Bu ders ağaç kurma aşamasını bir cümleyle geçti: sözcük birimi akışı bir ağaca çevrilir. Oysa o ağaç, sonraki her şeyin dayanağıdır — biçem ona uygulanır, yerleşim onun üzerinden hesaplanır, betikler onu değiştirir. Sonraki ders ağacın nasıl kurulduğunu adım adım gösterir: yığıt nasıl işler, kaynak metinde bulunmayan ögeler nasıl ortaya çıkar ve iki farklı yazımın neden aynı ağacı ürettiği.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat