DOM Nedir & Tarayıcılarda HTML Render İşlemi Nasıl Gerçekleşir?
Tags: webdev, javascript, dom, html
Published: 2023-03-05 14:33:30


DOM, bir W3C (World Wide Web Consortium) standardıdır. Programların ve komut dosyalarının bir belgenin içeriğine, yapısına ve stiline dinamik olarak erişmesine ve bunları güncellemesine olanak tanıyan, platform ve dilden bağımsız bir arabirimdir.

Bir web sayfası yüklendiğinde, tarayıcı sayfanın DOM ağacını oluşturur. Bu sayede JavaScript gibi betik diller ile sayfadaki tüm HTML özelliklerini değiştirebilir, mevcut HTML öğelerini ve nitelikliklerini kaldırabilir, yeni HTML öğeleri ve niteliklerini ekleyebilir veya sayfadaki tüm CSS stillerini değiştirebiliriz.

![Örnek HTML DOM Ağacı (Görselin kaynağı: [https://www.w3schools.com/js/pic_htmltree.gif](https://www.w3schools.com/js/pic_htmltree.gif))](https://cdn-images-1.medium.com/max/2000/1*LA6AXbzvC0IQ_d2H8v3NCw.gif)

**DOM Ağacı Nedir?**

DOM ağacı, düğümleri HTML veya XML belgesinin içeriğini temsil eden bir ağaç türüdür. Her HTML veya XML belgesinin benzersiz bir DOM ağacı temsili vardır. Örneğin aşağıdaki kodu inceleyelim:

    <html>
    <head>
      <title>My document</title>
    </head>
    <body>
      <h1>Header</h1>
      <p>Paragraph</p>
    </body>
    </html>

Yukarıdaki kod bloğunun DOM ağacı aşağıdaki gibidir:

![Örnek HTML DOM Ağacı 2](https://cdn-images-1.medium.com/max/2736/1*slkAIrjaKqzAMkj1QLocrw.png)

**Tarayıcılar HTML’yi Nasıl Render Eder?**

Bir web tarayıcısı, uzaktaki bir sunucudan dosyaları yükleyen ve bunları size görüntüleyerek kullanıcı etkileşimine izin veren bir yazılım parçasıdır. Uzaktaki bir sunucudan yüklenen dosyaların derlenmesi ve kullanıcıya gösterilmesi işlemi tarayıcı motorları ile yapılır. Eğer ilginizi çekiyorsa farklı tarayıcı motorlarını ve karşılaştırmalarını [inceleyebilirsiniz](https://en.wikipedia.org/wiki/Comparison_of_browser_engines).

İnternet üzerinden veriler byte paketleri olarak gönderilir. Tarayıcı ise bu veri byte’larını anladığı bir forma dönüştürmelidir. İlk olarak byte’lar HTML karakterlerine daha sonra ise Token’lara dönüştürülür. Sonraki adımda ise Token’lar düğümlere dönüştürülür. Düğümler belirli özelliklere sahip farklı nesnelerdir. Düğümler oluşturulduktan sonra DOM ağacı oluşturulur.

![DOM ağacının oluşturulma aşamaları (Görselin kaynağı: [web-dev](https://web-dev.imgix.net/image/C47gYyWYVMMhDmtYSLOWazuyePF2/cSL20piziX7XLekCPCuD.png?auto=format&w=845))](https://cdn-images-1.medium.com/max/2246/1*rW68P6kQ9mN-8yORGeWeGQ.png)

DOM ağacı oluşturulurken ilk önce “document” düğümü oluşturulur. Document tüm HTML belgesini temsil eden bir düğümdür. Bir HTML etiketini belirten düğüme ise “elements” denir. DOM ağacındaki herhangi bir düğümün türünü “nodeType” ile öğrenebiliriz. NodeType özelliği bir sayı döndürür. Bu sayının hangi düğüm tipini temsil ettiğini bulmak için ilgili dokümanı [inceleyebilirsiniz](https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType).

![document düğümünün türü](https://cdn-images-1.medium.com/max/2000/1*lM5e1_uQiIpIx1ZTNCCgEQ.png)

DOM ağacı başarıyla oluşturuldu ancak tarayıcının sayfayı oluşturabilmesi için öğelerin nasıl görüneceğine dair bilgilere ihtiyacı vardır. Bir sayfanın öğelerinin nasıl görünmesi gerektiği bilgisi CSSOM sorumluluğundadır.

**CSSOM Nedir?**

DOM ağacı oluşturulurken <head> içinde yer alan CSS bağlantısına bir istek gönderilir ve bu isteğin sonucunda CSS stilleri döner. HTML etiketlerinde olduğu gibi CSS bilgileri de byte’larla gelir ve belli aşamalardan geçerek CSS Nesne Modeli(CSSOM) oluşturulur.

![CSSOM ağaç yapısının oluşturulma aşamaları (Görselin kaynağı: [web-dev](https://web-dev.imgix.net/image/C47gYyWYVMMhDmtYSLOWazuyePF2/yb5YfU0vx6vHvB7c0fyD.png?auto=format&w=845))](https://cdn-images-1.medium.com/max/2024/1*N_atF-_2tffVlVhipNeeXw.png)

CSS byte’ları karakterlere, daha sonra token’lara ve düğümlere dönüştürülür; son olarak da CSS Nesne Modeli veya kısaca CSSOM olarak bilinen bir ağaç yapısı oluşturulur.

![CSSOM ağaç örneği (Görselin kaynağı: [web-dev](https://web-dev.imgix.net/image/C47gYyWYVMMhDmtYSLOWazuyePF2/keK3wDv9k2KzJA9QubFx.png?auto=format&w=650))](https://cdn-images-1.medium.com/max/2000/1*NBVI2PTPj7TXB6bOm4Yn6A.png)

**Render Tree Nedir?**

DOM ve CSSOM ağaç yapıları iki bağımsız yapılardır. DOM, sayfanın HTML öğesinin ilişkileri hakkındaki tüm bilgileri içerirken, CSSOM, öğelerin nasıl şekillendirileceğine ilişkin bilgileri içerir.

![DOM + CSSOM = Render Tree (Görselin kaynağı: [web-dev](https://web-dev.imgix.net/image/C47gYyWYVMMhDmtYSLOWazuyePF2/b6Z2Gu6UD1x1imOu1tJV.png?auto=format&w=845))](https://cdn-images-1.medium.com/max/2300/1*DDiTAbp5TzyntJFXLXOXHQ.png)

Render Tree, sayfadaki tüm görünür DOM içeriğiyle ilgili bilgileri ve farklı düğümler için gerekli tüm CSSOM bilgilerini içerir. Bir öğe CSS tarafından gizlenmişse (örneğin, display: none), düğümün Render Tree’de temsil edilmeyeceği anlamına gelir.

Gizli öğe(örneğin, display: none), DOM’de bulunur, ancak Render Tree içinde bulunmaz. Bunun nedeni, Render Tree’nin hem DOM’den hem de CSSOM’den gelen bilgileri birleştirmesidir.

Tarayıcı Render Tree oluştururken öncelikle DOM ağacının kökünden başlayarak görünür her bir düğümü işler. (script, meta gibi etiketler Render Tree içinde yer almazlar ayrıca CSS ile gizlenen düğümler de Render Tree içinde yer almazlar)
>  **visibility: hidden** ile **display: none** birbirinden farklıdır. İlki öğeyi görünmez yapar ancak öğe Render Tree içinde yer alır (boş bir düğüm olarak), buna karşılık ikincisi (display: none) öğeyi Render Tree’den çıkarır.

**Layout ve Paint Adımları**

Render Tree ile birlikte ekranda gösterilecek olan tüm içeriğe ve stil bilgilerine sahibiz ancak ekranda henüz bir görüntü oluşmadı. İlk olarak, tarayıcının sayfadaki her nesnenin tam boyutunu ve konumunu hesaplaması gerekir.

Her bir nesnenin kesin boyutunu ve konumunu belirlemek için tarayıcı, Render Tree’nin kökünden başlar ve sayfadaki her bir nesnenin hesaplamasını yapar. Bu hesaplama sonucunda her bir öğenin kesin konumu ve boyutu belirlenmiş olur. Bundan sonraki aşamada ise tarayıcı düğümleri tek tek ekrana boyar.

![Örnek HTML Çıktısı (Görselin kaynağı: [web-dev](https://web-dev.imgix.net/image/C47gYyWYVMMhDmtYSLOWazuyePF2/H9mc9hE33imsdh7TfCgm.png?auto=format&w=741))](https://cdn-images-1.medium.com/max/2000/1*Nrvw6_Qy_YQK5u5LNOW1qg.png)

**Render İşlemini Engelleyen Kaynaklar**

DOM ve CSSOM, boyama(paint) işleminden önce oluşturulmalıdırlar. HTML ve CSS’lerin mümkün olan en kısa sürede istemciye ulaşması, web uygulamalarının ilk render olma süresine kadar geçen süreyi optimize etmek için önemlidir.

Basit bir web sayfasında bile JS kullanılmış olma ihtimali yüksektir. Tarayıcı komut dosyalarını okurken bir script etiketiyle karşılaştığında DOM oluşturma süreci duraklatılır ve script dosyasının yürütülmesi bitene kadar durdurulur. Bunun nedeni, JavaScript’in hem DOM’yi hem de CSSOM’yi değiştirebilmesidir. Tarayıcı, JavaScript’in ne yapacağından emin olmadığı için, tüm DOM yapısını tamamen durdurarak önlem alır.

    <!DOCTYPE html>
    <html>
    
    <head>
        <meta name="viewport" content="width=device-width,initial-scale=1">
        <title>Örnek</title>
        <link rel="stylesheet" href="style.css">
        **<script src="app.js"></script>**
    </head>
    
    <body>
      .....
    </body>
    
    </html>

Yukarıdaki kod örneğinde tarayıcı script etiketine geldiğinde script dosyasının yürütülmesi bitene kadar DOM oluşturma süreci durdurulacaktır. Farklı bir senaryo olarak app.js dosyası local’de değil de bir sunucudan çekiliyor olsaydı ve ağ bağlantısından dolayı app.js’yi getirmek saniyeler sürüyor olsaydı, DOM yapım işlemi de saniyelerce durdurulacaktı.

Yine farklı bir senaryo ile devam edelim, örneğin tarayıcı bir script etiketiyle karşılaştığında CSSOM henüz hazır değilse, JS yürütme işlemi CSSOM hazır olana kadar bekletilecektir.

Varsayılan olarak tarayıcı her script etiketiyle karşılaştığında DOM yapım süreci durdurulacaktır. Eğer script etiketinize “async” anahtar sözcüğünü eklerseniz DOM yapımı durdurulmayacak ve script dosyası indirilip hazır olduğunda çalıştırılacaktır.

    <!DOCTYPE html>
    <html>
    
    <head>
        <meta name="viewport" content="width=device-width,initial-scale=1">
        <title>Örnek</title>
        <link rel="stylesheet" href="style.css">
        **<script src="https://random-app.js" async></script>**
    </head>
    
    <body>
      .....
    </body>
    
    </html>

**Kaynaklar**

* [https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction)

* [https://www.w3schools.com/js/js_htmldom.asp](https://www.w3schools.com/js/js_htmldom.asp)

* [https://en.wikipedia.org/wiki/Comparison_of_browser_engines](https://en.wikipedia.org/wiki/Comparison_of_browser_engines)

* [https://en.wikipedia.org/wiki/Web_browser](https://en.wikipedia.org/wiki/Web_browser)

* [https://developer.mozilla.org/en-US/docs/Web/API/CSS_Object_Model](https://developer.mozilla.org/en-US/docs/Web/API/CSS_Object_Model)

* [https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType](https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType)

* [https://developer.mozilla.org/en-US/docs/Web/Performance/How_browsers_work](https://developer.mozilla.org/en-US/docs/Web/Performance/How_browsers_work)

* [https://starkie.dev/blog/how-a-browser-renders-a-web-page](https://starkie.dev/blog/how-a-browser-renders-a-web-page)