İletişim

Sanal DOM (Virtual DOM) Nedir?

Kısa tanım

Sanal DOM (virtual DOM), arayüzün olması gereken hâlinin bellekte JavaScript nesneleri olarak tutulan hafif bir temsilidir. React gibi kütüphaneler durum değiştiğinde yeni bir sanal ağaç üretir, bunu öncekiyle karşılaştırır (reconciliation) ve gerçek DOM'a yalnızca farkları uygular. Bu yöntem, geliştiricinin DOM'u adım adım değiştirmek yerine arayüzün son hâlini tarif etmesine olanak tanır; ancak elle yazılmış hedefli DOM güncellemelerinden her zaman daha hızlı değildir.

Diğer adları: virtual DOM, VDOM, sanal DOM ağacı

Durum değişince yeni sanal DOM'un öncekiyle karşılaştırıldığı ve yalnızca değişen düğümlerin gerçek DOM'a uygulandığı akış

Doğrudan DOM güncellemesi ile karşılaştırma

Klasik yaklaşımda geliştirici, bir şey değiştiğinde DOM üzerinde ne yapılacağını tek tek yazar: şu öğeyi bul, metnini değiştir, şu sınıfı ekle, şu listeye yeni bir satır koy. Uygulama büyüdükçe, ekrandaki her parçanın hangi olayda nasıl güncelleneceğini takip etmek zorlaşır ve "veri değişti ama ekran eski kaldı" türü hatalar çoğalır.

Sanal DOM yaklaşımında geliştirici, verinin o anki hâline göre arayüzün nasıl görünmesi gerektiğini tarif eder. Kütüphane bu tarifi bellekte bir nesne ağacına çevirir, önceki ağaçla karşılaştırır ve gerçek DOM'a gereken en küçük değişiklik setini uygular. React'in eski dokümantasyonu kavramı "arayüzün ideal ya da sanal bir temsilinin bellekte tutulup ReactDOM gibi bir kütüphane tarafından gerçek DOM ile eşitlenmesi" olarak tanımlar; bu eşitleme sürecine reconciliation denir.

Bir güncellemenin adımları

  1. Render: Durum veya props değişir; ilgili bileşen fonksiyonu yeniden çalışır ve yeni bir öğe ağacı döndürür.
  2. Karşılaştırma: Kütüphane yeni ağacı öncekiyle eşleştirir ve hangi niteliklerin, metinlerin ya da alt öğelerin değiştiğini hesaplar.
  3. Commit: Yalnızca değişen DOM düğümlerine dokunulur. React'in güncel dokümantasyonu bunu açıkça söyler: React, DOM düğümlerini yalnızca iki render arasında fark varsa değiştirir. Bu yüzden kullanıcının bir input alanına yazdığı metin, bileşen yeniden render edildiğinde kaybolmaz.

React'in iki varsayımı ve key

İki ağacı genel bir algoritmayla en az işlemle karşılaştırmak çok pahalıdır; React'in eski dokümantasyonu bilinen genel algoritmaların O(n³) karmaşıklıkta olduğunu belirtir. React bunun yerine iki varsayıma dayanan doğrusal bir sezgi kullanır: farklı türdeki öğeler farklı ağaçlar üretir ve geliştirici, hangi alt öğelerin render'lar arasında aynı kaldığını key ile belirtebilir.

// Aynı konumda farklı bileşen türü: alt ağaç ve içindeki state sıfırlanır
{isLoggedIn ? <Dashboard /> : <LoginForm />}

// Liste öğelerinde dizin yerine kalıcı bir kimlik kullanılmalı
{items.map((item) => <Row key={item.id} item={item} />)}

Dizini key olarak kullanmak, liste yeniden sıralandığında yanlış satırların yeniden kullanılmasına, kontrolsüz input'larda değerlerin yer değiştirmesine yol açabilir. React'in state koruma rehberi, aynı konumdaki aynı bileşenin state'ini koruduğunu ve key'in bu eşleşmeyi bilinçli olarak değiştirmek için kullanılabileceğini örneklerle anlatır.

"Sanal DOM her zaman daha hızlıdır" yanılgısı

Sanal DOM, DOM'a ek olarak çalışan bir katmandır; her güncellemede yeni bir ağaç oluşturmak ve karşılaştırmak işlemci zamanı ve bellek harcar. Ne değişeceğini tam olarak bilen, elle yazılmış hedefli bir DOM güncellemesi bu ek işi yapmaz ve teorik olarak daha hızlıdır. Sanal DOM'un asıl kazancı başka yerdedir: geliştirici bildirimsel (declarative) kod yazar, kütüphane gereksiz DOM işlemlerini ayıklar ve büyük bir uygulamada makul bir performans kendiliğinden elde edilir. Svelte gibi derleme tabanlı araçlar ve Solid gibi ince taneli reaktivite kullanan kütüphaneler, aynı bildirimsel modeli sanal DOM karşılaştırması yapmadan sunmayı tercih eder.

Pratikte performans sorunları çoğunlukla sanal DOM'un kendisinden değil, gereksiz yere yeniden render edilen büyük bileşen ağaçlarından, çok büyük listelerden ve ağır JavaScript paketlerinden kaynaklanır.

Arama motorları ve sunucu tarafı

Sanal DOM yalnızca tarayıcıda çalışan JavaScript'in içinde var olur; arama motoru tarayıcıları onu görmez, yalnızca ortaya çıkan HTML'i ve render edilmiş DOM'u değerlendirir. Sunucuda üretilen HTML'in tarayıcıda React tarafından devralınması sürecine hydration denir; bu aşamada React, sunucudan gelen DOM'u kendi ağacıyla eşleştirir ve iki taraf uyuşmazsa uyarı verir.

İlgili terimler

← Sözlüğe dön