Ders 04 / 25
Kaynak Yükleme Sırası
Betik ve biçem dosyalarının ayrıştırmayı ve çizimi nasıl beklettiği; erteleme ve eşzamansız yükleme kiplerinin bir olay çizelgesi üzerinden karşılaştırılması.
İçindekiler
Önceki ders ağacın sözcük birimi akışından kesintisiz kurulduğunu varsaydı. Gerçek belgeler bu varsayımı bozar: ayrıştırma sürerken belge kendisinden başka kaynaklara başvurur ve bu başvuruların bir bölümü ayrıştırmayı durdurur.
İnternet Nasıl Çalışır kursundaki Tarayıcı Ne Yapar dersi bu alt kaynak isteklerinin varlığını göstermişti: bir adres yazıldığında sunucu birden çok istek görüyordu. Bu ders, o isteklerin ne zaman yapıldığını ve belgenin işlenmesini nasıl etkilediğini ele alır. Konu bir başarım ayrıntısı değil, belgenin nasıl yazılacağını belirleyen bir kısıttır.
Başvuru Ayrıştırma Sırasında Doğar
Tarayıcı belgeyi baştan sona okur. link ögesini gördüğü anda biçem dosyasının isteğini
yollar, img ögesini gördüğü anda görselin isteğini yollar. Belgenin sonunu beklemez.
Bunun doğrudan sonucu şudur: bir kaynağın belgedeki yeri, istendiği anı belirler.
Belgenin sonuna yazılan bir biçem dosyası, başına yazılana göre daha geç istenir.
Kaynakların ayrıştırma üzerindeki etkisi aynı değildir. Üç davranış vardır.
| Kaynak | Ayrıştırmayı durdurur | Çizimi bekletir |
|---|---|---|
| Görsel | Hayır | Hayır |
Biçem dosyası (link rel="stylesheet") |
Hayır | Evet |
| Betik (öznitelik yazılmamış) | Evet | Dolaylı olarak |
Betik (defer) |
Hayır | Hayır |
Betik (async) |
Yürütülürken | Dolaylı olarak |
Betik Ayrıştırmayı Neden Durdurur
Öznitelik yazılmamış bir betik ögesi görüldüğünde ayrıştırma durur, betik indirilir, yürütülür ve ancak sonra ayrıştırmaya devam edilir. Bu davranış bir eksiklik değil, bir zorunluluktur: betik, o ana kadar kurulmuş ağacı okuyabilir ve ona düğüm ekleyebilir. Ayrıştırıcı aynı anda çalışsaydı, betiğin gördüğü ağaç ile ayrıştırıcının kurduğu ağaç çakışırdı.
Bu zorunluluğun bedeli, betik indirilirken belgenin geri kalanının işlenmemesidir. Bedeli ödememenin iki yolu vardır ve ikisi de betiğin ağaca ne zaman erişeceğine ilişkin bir söz verir.
Erteleme (defer): betik ayrıştırmayı durdurmadan indirilir, ayrıştırma bittikten
sonra yürütülür. Birden çok ertelenmiş betik, belgedeki yazılış sırasına göre yürütülür.
Bu, birbirine bağımlı betikler için tek güvenli kiptir.
Eşzamansız (async): betik ayrıştırmayı durdurmadan indirilir ve indiği anda
yürütülür; yürütme sırasında ayrıştırma durur. Yürütme sırası indirme sırasına bağlıdır,
belgedeki sıraya değil. Başka betiklere bağımlı olmayan, tek başına çalışan betikler
içindir.
Bu ayrım bir tercih değil, bir sözleşmedir: async yazmak “sıramın bir önemi yok”
demektir. Sırası önemli olan bir betiğe bu öznitelik yazılırsa, hata belirli koşullarda
ortaya çıkar ve yeniden üretilmesi güçtür.
Biçem Dosyası Neden Çizimi Bekletir
Biçem dosyası ayrıştırmayı durdurmaz — ağaç kurulmayı sürdürür. Ancak biçem hesabı tamamlanmadan çizim yapılamaz; yapılsaydı sayfa önce biçemsiz görünür, sonra biçemli görünüme atlardı. Tarayıcı bunun yerine bekler.
İkinci ve daha az bilinen bir kural daha vardır: bekleyen bir biçem dosyası varken betik yürütülmez. Gerekçesi aynı türdendir. Betik, bir ögenin hesaplanmış biçem değerini sorabilir; henüz uygulanmamış bir kural varsa alacağı yanıt yanlış olur. Bu nedenle betik, kendisi inmiş olsa bile biçem dosyası inene kadar bekletilir.
Olay Çizelgesi
Aşağıdaki betik bu kuralları bir olay modeli olarak çalıştırır. Gerçek bir tarayıcı değil, kuralların modelidir: her belge parçası bir birim ayrıştırma süresi tutar, her kaynağın getirme süresi verilidir.
// yukleme.mjs — ayristirma-yukleme kurallarinin olay modeli const belge = [ { tur: "isaretleme", ad: "head baslangici", sure: 1 }, { tur: "kaynak", ad: "bicem.css", bicim: "bicem", getirme: 6 }, { tur: "isaretleme", ad: "govde ilk yarisi", sure: 2 }, { tur: "kaynak", ad: "olcum.js", bicim: "betik", kip: "engelleyen", getirme: 3, yurutme: 1 }, { tur: "isaretleme", ad: "govde ikinci yarisi", sure: 2 }, { tur: "kaynak", ad: "grafik.js", bicim: "betik", kip: "ertelenen", getirme: 5, yurutme: 1 }, { tur: "isaretleme", ad: "govde sonu", sure: 1 }, ]; const gunluk = []; let saat = 0; const ertelenenler = []; let bicemHazir = Infinity; for (const parca of belge) { if (parca.tur === "isaretleme") { gunluk.push([saat, saat + parca.sure, "ayristirma: " + parca.ad]); saat += parca.sure; continue; } if (parca.bicim === "bicem") { gunluk.push([saat, saat, "istek: " + parca.ad + " (arka planda)"]); bicemHazir = saat + parca.getirme; continue; } if (parca.kip === "engelleyen") { const getirmeBitis = saat + parca.getirme; const yurutmeBaslangic = Math.max(getirmeBitis, bicemHazir); gunluk.push([saat, getirmeBitis, "DURDU: " + parca.ad + " getiriliyor"]); if (yurutmeBaslangic > getirmeBitis) { gunluk.push([getirmeBitis, yurutmeBaslangic, "DURDU: bekleyen bicem"]); } gunluk.push([yurutmeBaslangic, yurutmeBaslangic + parca.yurutme, "yurutme: " + parca.ad]); saat = yurutmeBaslangic + parca.yurutme; continue; } if (parca.kip === "ertelenen") { gunluk.push([saat, saat, "istek: " + parca.ad + " (arka planda)"]); ertelenenler.push({ ...parca, hazir: saat + parca.getirme }); } } const ayristirmaBitis = saat; gunluk.push([saat, saat, "ayristirma tamamlandi"]); for (const betik of ertelenenler) { const baslangic = Math.max(saat, betik.hazir); gunluk.push([baslangic, baslangic + betik.yurutme, "yurutme (ertelenen): " + betik.ad]); saat = baslangic + betik.yurutme; } for (const [bas, bit, ad] of gunluk) { console.log(String(bas).padStart(3) + " - " + String(bit).padStart(3) + " " + ad); } console.log("ayristirma bitisi:", ayristirmaBitis, "| tum betikler bitti:", saat);
0 - 1 ayristirma: head baslangici 1 - 1 istek: bicem.css (arka planda) 1 - 3 ayristirma: govde ilk yarisi 3 - 6 DURDU: olcum.js getiriliyor 6 - 7 DURDU: bekleyen bicem 7 - 8 yurutme: olcum.js 8 - 10 ayristirma: govde ikinci yarisi 10 - 10 istek: grafik.js (arka planda) 10 - 11 ayristirma: govde sonu 11 - 11 ayristirma tamamlandi 15 - 16 yurutme (ertelenen): grafik.js ayristirma bitisi: 11 | tum betikler bitti: 16
Çizelge üç şeyi görünür kılar. Birincisi, olcum.js üç birim boyunca ayrıştırmayı
durdurmuştur (3–6 aralığı) ve indikten sonra bile bir birim daha beklemiştir; beklediği
şey bicem.css dosyasının hazır olmasıdır. İkincisi, grafik.js ertelenmiş olduğu için
ayrıştırmayı hiç durdurmamış, isteği 10. birimde çıkmış ve ayrıştırma bittikten sonra
yürütülmüştür. Üçüncüsü, ayrıştırmanın bitişi (11) ile betiklerin bitişi (16) ayrı
büyüklüklerdir; belge okunabilir duruma geldiğinde tüm davranış katmanı henüz hazır
olmayabilir.
Sayılar bu modelin varsayımlarıdır; gerçek süreler ağ koşullarına ve dosya boyutlarına bağlıdır. Değişmeyen şey sıralamadır.
Yerleştirme Kararları
Kurallar birkaç doğrudan sonuca varır.
Biçem dosyası belgenin baş bölümüne yazılır. Geç istenirse çizim geç başlar; gövdenin ortasına yazılırsa, o noktaya kadar çizilmiş içerik sonradan yeniden biçemlenir.
Ayrıştırmayı durdurmayan bir betik kipi, öznitelik yazılmamış betiğe yeğlenir. Belgenin sonuna yazmak da ayrıştırmanın büyük bölümünü kurtarır ancak erteleme kadar erken indirme başlatmaz: sona yazılan betiğin isteği ancak ayrıştırıcı oraya vardığında çıkar.
Ayrıştırıcı durduğunda tarayıcı boş oturmaz. Belgenin ileri bölümlerini yalnızca kaynak başvurusu aramak için önden tarayan bir düzenek, bulduğu istekleri erkenden yollar. Bu davranış, kaynakların belgede açıkça bildirilmiş olmasına dayanır: adresi bir betiğin hesaplayarak ürettiği bir kaynak bu taramada görünmez.
Özet
- Kaynak istekleri ayrıştırma sırasında doğar; bir kaynağın belgedeki yeri, istendiği anı belirler.
- Öznitelik yazılmamış betik ayrıştırmayı durdurur, çünkü betik o ana kadar kurulmuş ağacı okuyabilir ve değiştirebilir.
- Erteleme, betiği ayrıştırma bittikten sonra ve belgedeki sırayla yürütür; eşzamansız kip indiği anda yürütür ve sıra vermez.
- Biçem dosyası ayrıştırmayı durdurmaz ama çizimi bekletir; ayrıca bekleyen biçem varken betik yürütülmez.
- Ayrıştırmanın bitişi ile betiklerin bitişi ayrı anlardır; belgenin okunabilir olması tüm davranışın hazır olması demek değildir.
Sonraki Adım
Bu konu, belgenin nasıl işlendiğini kurdu: baytların ağaca çevrilmesi, ağacın kutulara dönüşmesi, kaynakların bu zincire etkisi. Sonraki konu belgenin kendisini yazmaya başlar. İlk soru, her belgenin en dışındaki yapıdır: belge türü bildiriminin ne işe yaradığı, baş ve gövde bölümlerinin ne ayırdığı ve bunların hiçbiri yazılmadığında ayrıştırıcının ne kurduğu.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.