Tarayıcının sayfayı oluşturabilmesi için öncelikle DOM ve CSSOM ağaçlarını oluşturması gerekir. Bu nedenle, hem HTML'yi hem de CSS'yi tarayıcıya mümkün olduğunca hızlı bir şekilde sunduğumuzdan emin olmalıyız.
Özet
- Bayt → karakter → belirteç → düğümler → nesne modeli.
- HTML işaretlemesi, Belge Nesne Modeli'ne (DOM); CSS işaretlemesi ise CSS Nesne Modeli'ne (CSSOM) dönüştürülür.
- DOM ve CSSOM, bağımsız veri yapılarıdır.
- Chrome Geliştirici Araçları Performans paneli, DOM ve CSSOM'nin oluşturma ve işleme maliyetlerini yakalamamıza ve denetlememize olanak tanır.
Belge Nesne Modeli (DOM)
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link href="style.css" rel="stylesheet" />
<title>Critical Path</title>
</head>
<body>
<p>Hello <span>web performance</span> students!</p>
<div><img src="awesome-photo.jpg" /></div>
</body>
</html>
Mümkün olan en basit durumla başlayalım: kısa bir metin ve tek bir resim içeren düz bir HTML sayfası. Tarayıcı bu sayfayı nasıl işler?
- Dönüşüm: Tarayıcı, diskten veya ağdan HTML'nin ham baytlarını okur ve bunları, dosyanın belirtilen kodlamasına (ör. UTF-8) göre bağımsız karakterlere çevirir.
- Jetonlama: Tarayıcı, karakter dizelerini farklı jetonlara dönüştürür. W3C HTML5 standardında belirtildiği gibi, "<html>", "<body>" ve açılı ayraç içindeki diğer dizeler. Her jetonun anlamı farklıdır ve kendi kuralları vardır.
- Lexing: Yayılan jetonlar, özelliklerini ve kurallarını tanımlayan "nesnelere" dönüştürülür.
- DOM oluşturma: Son olarak, HTML işaretlemesi farklı etiketler arasındaki ilişkileri tanımladığından (bazı etiketler diğer etiketlerin içinde yer alır) oluşturulan nesneler, orijinal işaretlemede tanımlanan üst-alt ilişkilerini de yakalayan bir ağaç veri yapısına bağlanır: HTML nesnesi, body nesnesinin üst öğesidir; body, paragraf nesnesinin üst öğesidir ve bu böyle devam eder.
Tüm bu sürecin son çıkışı, basit sayfamızın Belge Nesne Modeli'dir (DOM). Tarayıcı bu modeli, sayfanın sonraki tüm işlemleri için kullanır.
Tarayıcı, HTML işaretlemesini her işlediğinde yukarıdaki tüm adımları uygular: baytları karaktere dönüştürme, jetonları tanımlama, jetonları düğümlere dönüştürme ve DOM ağacını oluşturma. Tüm bu süreç, özellikle de işlenecek büyük HTML miktarımız olduğunda biraz zaman alabilir.
Chrome Geliştirici Araçları'nı açar ve sayfa yüklenirken bir zaman çizelgesi kaydederseniz bu adımı gerçekleştirmek için geçen gerçek süreyi görebilirsiniz. Yukarıdaki örnekte, bir HTML parçasını DOM ağacına dönüştürmemiz yaklaşık 5 ms sürmüştür. Daha büyük bir sayfada bu işlem çok daha uzun sürebilir. Akıcı animasyonlar oluştururken, tarayıcının büyük miktarda HTML kodu işlemesi gerekiyorsa bu durum kolayca bir performans sorununa yol açabilir.
DOM ağacı, belge işaretlemesinin özelliklerini ve ilişkilerini yakalar ancak öğenin oluşturulduğunda nasıl görüneceğini belirtmez. CSSOM'nin sorumluluğu da budur.
CSS Nesne Modeli (CSSOM)
Tarayıcı, basit sayfamızın DOM'sini oluştururken dokümanın başlık bölümünde harici bir CSS stil sayfasına referans veren bir bağlantı etiketiyle karşılaştı: style.css
. Sayfayı oluşturmak için bu kaynağın gerektiğini tahmin ederek hemen bu kaynak için bir istek gönderir ve bu istek aşağıdaki içerikle geri gelir:
body {
font-size: 16px;
}
p {
font-weight: bold;
}
span {
color: red;
}
p span {
display: none;
}
img {
float: right;
}
Stillerimizi doğrudan HTML işaretlemesinin içinde (satır içi) açıklayabilirdik, ancak CSS'mizi HTML'den bağımsız tutmak, içerik ve tasarımı ayrı ayrı değerlendirmemize olanak tanır: Tasarımcılar CSS üzerinde çalışırken, geliştiriciler HTML'ye odaklanabilir ve bu şekilde devam eder.
HTML'de olduğu gibi, alınan CSS kurallarını da tarayıcının anlayıp çalışabileceği bir şeye dönüştürmemiz gerekir. Bu nedenle, HTML işlemini bu defa HTML yerine CSS için tekrarlarız:
CSS baytları; karakterlere, ardından jetonlara, daha sonra düğümlere dönüştürülür ve son olarak "CSS Nesne Modeli" (CSSOM) olarak bilinen bir ağaç yapısına bağlanır.
CSSOM'nin neden ağaç yapısı vardır? Sayfadaki herhangi bir nesnenin son stil grubunu hesaplarken, tarayıcı o düğüm için geçerli olan en genel kuralla başlar (örneğin, bir gövde öğesinin alt öğesiyse tüm gövde stilleri uygulanır) ve ardından daha spesifik kurallar (yani "aşağı basamaklama" kuralları) uygulayarak hesaplanan stilleri yinelemeli şekilde hassaslaştırır.
Konuyu daha somut hale getirmek için yukarıdaki CSSOM ağacını düşünün. Gövde öğesinin içine yerleştirilen <span>
etiketi içinde bulunan tüm metinlerin yazı tipi boyutu 16 pikseldir ve kırmızı renktedir. font-size
yönergesi, body
değerinden span
değerine basamaklanır. Ancak span
etiketi, bir paragraf (p
) etiketinin alt öğesiyse içeriği gösterilmez.
Ayrıca, yukarıdaki ağacın CSSOM ağacının tamamı olmadığını ve yalnızca stil sayfamızda geçersiz kılmaya karar verdiğimiz stilleri gösterdiğini unutmayın. Her tarayıcı, "kullanıcı aracısı stilleri" olarak da bilinen bir varsayılan stil grubu sağlar. Kendi stilimizi sağlamadığımızda bunu görürüz ve stillerimiz sadece bu varsayılanları geçersiz kılar.
CSS işlemenin ne kadar sürdüğünü öğrenmek için DevTools'da bir zaman çizelgesi kaydedip "Recalculate Style" (Stili Yeniden Hesapla) etkinliğini arayabilirsiniz. DOM ayrıştırmanın aksine, zaman çizelgesi ayrı bir "CSS Ayrıştır" girişi göstermez. Bunun yerine, ayrıştırma ve CSSOM ağaç yapısı ile bu tek etkinlik altında hesaplanan stillerin yinelenen hesaplanma yöntemini yakalar.
Basit stil sayfamızın işlenmesi yaklaşık 0,6 ms sürer ve sayfadaki sekiz öğeyi etkiler.Çok fazla değil ama yine de ücretsiz değildir. Peki, sekiz öğe nereden geldi? CSSOM ve DOM, bağımsız veri yapılarıdır! Bu durumda, tarayıcının önemli bir adımı gizlediğini öğreniyoruz. Şimdi, DOM ve CSSOM'yi birbirine bağlayan oluşturma ağacından bahsedelim.