Sanal Belge Nesne Modeli (DOM) kavramı ilk olarak 2013 yılında JavaScript çerçevesi React tarafından tanıtıldı ve bugün hem React hem de Vue.js gibi diğer çerçeveler tarafından hala kullanılıyor. Buradaki fikir, gerekli DOM manipülasyonu sayısını en aza indirmek ve değişikliklerin tespit edilmesini kolaylaştırmak için web sitesinin yapısının soyut bir temsilini bellekte tutmaktır. Uygulamada bu, iki adım gerektirir: sanal bir DOM ağacı oluşturmak için kaynak kodun ayrıştırılması gerekir ve bir bileşenin görünümünü güncellemesini gerektiren herhangi bir veri değişikliğinde, hem sanal DOM'un hem de DOM'un güncellenmesi gerekir.
Duyuru
Timo Zander uygulamalı matematik ve bilgisayar bilimleri okudu ve yazılım geliştiricisi olarak çalışıyor. Açık kaynak, JavaScript evreni ve gelişen teknolojilerle ilgileniyor.
Bu güncellemeler hızla çok karmaşık hale gelebilir. Çerçevenin, mevcut görüntülenen HTML öğelerinin ve bileşenlerinin dayandığı önceki verilerle karşılaştırmak için yeni verilere dayalı yeni bir sanal DOM ağacı oluşturması gerekir. Saf bir uygulamada, çerçeve DOM'un tamamını yeniden oluşturabilir (aracılığıyla) document.innerHTML = "…") her zaman. Ancak bu, özellikle büyük web siteleri için son derece yavaş olacaktır. Bunun yerine, sanal DOM tabanlı çerçeveler, sanal DOM'un iki sürümü arasındaki, genellikle farklılık veya mutabakat olarak adlandırılan belirli farkları bulmaya çalışır.
Şekil 1'de gösterilen React uygulamasını düşünün. Her saniye, değişen zamanı görüntülemek için zaman ekranının yeniden oluşturulması gerekir. Kullanıcı adı girişi her değiştirildiğinde, uygulamanın bu bölümünün de değişen giriş değerini yansıtacak şekilde yeniden oluşturulması gerekir. Bu durumda diff prosedürü oldukça basittir: React'ın sanal DOM ağacını geçmesi ve iki yaprak bileşeninin durum farklılıklarını not etmesi gerekir. UsernameInput VE Time. Sonuç olarak DOM'un yalnızca bu iki küçük bölümünü yönetir. Daha büyük web siteleri için bu süreç giderek daha karmaşık hale gelebilir. Veri akışları daha karmaşık ve birbirine bağımlıdır, durum birçok bileşende yeniden kullanılabilir ve HTML öğelerinin toplam sayısı artar. Tüm bu koşullar, herhangi bir farklılaştırma algoritması için zorluk teşkil eder; bu nedenle, bu süreci hızlandırmak ve istikrarlı bir güncelleme hızı elde etmek için optimizasyonlara ve buluşsal yöntemlere ihtiyaç vardır. Bu stratejilerin bazıları Vue.js çerçevesinde uygulanmaktadır.
Basit bir örnek uygulamanın sanal DOM ağacı (Şekil 1).
(Fotoğraf: Timo Zander)
Vue.js: çalışma zamanı ve derleyici birlikte çalışır
Vue.js, sanal DOM güncellemelerini işlemenin daha kesin bir yolunu uygular. Tek dosya bileşenleri (SFC) sayesinde çerçeve her zaman Vue.js kodunu standart JavaScript'e dönüştüren bir derleme aşamasına güvenmiştir. Ancak sözdizimini dönüştürmenin yanı sıra, derleyici aynı zamanda kodu analiz eder ve çalışma zamanının onu daha verimli bir şekilde yürütmek için kullanabileceği yapısı hakkında bilgi bırakır. Bu “derleyici bilgili sanal DOM” yaklaşımı, Vue.js'nin işleme performansının kıyaslama testlerinde düzenli olarak React'ı geçmesine olanak tanıyan şeydir. Örneğin, Vue.js, sanal DOM ağacının içinde statik HTML kodu parçaları bulduğunda, derleyici bunları oluşturma işlevinden kurtarır (Liste 1). Bu, site her değiştiğinde bu sanal düğümleri yeniden oluşturmak yerine çalışma zamanının her işleme için başlangıçta oluşturulan öğeleri yeniden kullandığı anlamına gelir. Çalışma zamanı, nesneleri yalnızca bir kez tahsis ederek, her işlemeden sonra kullanılmayan nesnelerin çöp toplama ihtiyacını ortadan kaldırır ve referans eşitliğini kullanarak öğeleri ayırt edebilir.
<div>
<div>foo</div> <!-- hoisted -->
<div>bar</div> <!-- hoisted -->
<div>{{ dynamic }}</div>
</div>
// Compiled:
const _hoisted_1 = /*#__PURE__*/_createElementVNode("div", null, "foo", -1 /* HOISTED */)
const _hoisted_2 = /*#__PURE__*/_createElementVNode("div", null, "bar", -1 /* HOISTED */)
export function render(_ctx, _cache, $props, $setup, $data, $options) {
return (_openBlock(), _createElementBlock("div", null, [
_hoisted_1,
_createCommentVNode(" hoisted "),
_hoisted_2,
_createCommentVNode(" hoisted "),
_createElementVNode("div", null, _toDisplayString(_ctx.dynamic), 1 /* TEXT */)
]))
}
Liste 1: Derlenmiş oluşturma işlevi, statik HTML öğeleri için sanal düğümleri yeniden oluşturmaz.
Vue.js yama bayrakları başka bir merkezi mekanizmadır. Bunlar, derleyicinin dinamik düğümlere atadığı ve çalışma zamanını bu düğümlerin nasıl değişebileceği konusunda bilgilendiren etiketlerdir: örneğin, bazı düğümler yalnızca stillerini değiştirebilir veya bir özelliğin değerini güncelleyebilirken diğerleri tamamen dinamik bir iç yapıya sahiptir. Kodu çalıştırdığınızda, çalışma zamanının yalnızca bir düğümün yama bayraklarına dayalı olarak belirli güncellemeleri ve kontrolleri gerçekleştirmesi gerekir.
Karşılaştırmayı hızlandırmak için bayraklar, bitsel yöntem kullanılarak karşılaştırılan bit maskeleri (Liste 2) olarak ifade edilir. AND Şebeke. Yama işaretleri, bir bileşenin değişebileceği tüm olası yolları kapsamaz ancak en yaygın durumları optimize etmeyi amaçlar. Örneğin, yalnızca dinamik metin içeriğine sahip düğümler (Dinamik div Liste 1'de) derleyiciye, düğümün çocuklarını (dizge olan) aşağıdaki yöntemi kullanarak karşılaştırmasını söyleyen bir bayrak alır eqeqeq operatöre başvurun ve gerekirse değiştirin.
export enum PatchFlags {
TEXT = 1, // 00000000000000000000000000000001
CLASS = 1 << 1, // 00000000000000000000000000000010
STYLE = 1 << 2, // 00000000000000000000000000000100
PROPS = 1 << 3, // 00000000000000000000000000001000
// ... more flags
}
Liste 2: Karşılaştırma performansını artırmak için yama bayrakları bit maskesi olarak saklanır.
Dinamik HTML nitelikleri de belirli bir bayrak alır: ortak varlıkları ve Vue.js'nin JavaScript nesnelerini bu nesnelere aktarmayı desteklemesi nedeniyle hem sınıf hem de stil niteliklerinin de özel bir bayrağı vardır. Derleyici, oluşturma işlevini oluşturmadan önce bu özelliklere ilişkin tüm girdileri nesnenin biçimine göre normalleştirir. Diğer donanımlar için Vue.js, dosyayı alan normal dinamik donanımları birbirinden ayırır. PROPS bayraklar ve yalnızca değerlerin değil, aynı zamanda donanımların da dinamik olduğu destekler; FULL_PROPS bayrak (Liste 3).
// Static props
<BlogPost title="Understanding the Vue compiler magic" /> >
// Static props with dynamic value
<BlogPost :title="title" /> >
// Dynamic props
const post = {
id: 1,
title: 'My Journey with Vue'
}
<BlogPost v-bind="post" />
Listeleme 3: Prop'lar dinamik değerlere sahipken statik olabileceği gibi tamamen dinamik de olabilir.
Vue.js, özelliklerin değişmediğini, yalnızca değerlerinin değiştiğini bildiğinde, bu aksesuarlar için eski ve yeni bileşenlerin değerlerini karşılaştırarak farkı hızlandırabilir. Ancak dinamik donanımlar, çalışma zamanının her iki bileşendeki mevcut tüm donanımları karşılaştırmasını gerektirir. React, Svelte ve Vue.js de dahil olmak üzere çoğu ön uç çerçevesi, kullanıcıların bir nesne listesi oluştururken bir öğe anahtarı belirtmesini de önerir. Anahtar kullanıldığında çalışma zamanı, olası değişiklikleri uygulamak için yeniden oluşturma öncesinde ve sonrasında aynı düğümü verimli bir şekilde tanımlayabilir. Aynı zamanda mevcut olmayan anahtarlar nedeniyle kaldırılan veya eklenen düğümleri sırasıyla yeni veya eski durumda hızlı bir şekilde bulabilir (Şekil 2). Bu anahtarlar dinamik bir listedeki bir düğümü benzersiz şekilde tanımlamak için kullanıldığından, kararlı ve benzersiz olmaları gerekir.
Anahtarlar, dinamik olarak oluşturulmuş bir listede Vue.js çalışma zamanı farklarını daha verimli bir şekilde düzenlemenize olanak tanır (Şekil 2).
(Fotoğraf: Timo Zander)
Üzerinde bulunduğu eleman "v-for" ifade bulunur ve ardından alır "KEYED_FRAGMENT" VEYA "UNKEYED_FRAGMENT" tuşların belirtilip belirtilmemesine bağlı olarak bayrak. Bu, çalışma zamanının, anahtarların en azından kısmen mevcut olduğuna güvenebileceğini bilmesi durumunda en iyi performans gösteren algoritmayı seçmesine olanak tanır. Üstelik, HOISTED VE BAIL Varsa her zaman bir öğenin tek bayrağı olan özel yama bayraklarıdır. Bu durumuda HOISTED flag'ı kullanarak çalışma zamanı, hiçbir zaman nemlendirilmesi gerekmeyen statik içeriği işaretlediğinden bileşen alt ağacını tamamen atlayabilir ve BAIL bayrağı, bir bileşenin optimize edilmemiş kaba kuvvet farkı algoritması kullanılarak işlenmesi gerektiğini belirtir.
Bu tür kaydetmeyi tetikleyen düğümler, genellikle kullanıcılar Vue.js'nin şablon derleyicisine güvenmek yerine bir işleme işlevini manuel olarak yazdıklarında oluşturulur, çünkü manuel işleme işlevleri herhangi bir yama bayrağı taşımaz. Bir Vue.js bileşeni birden fazla kök düğüme sahip olduğunda, derleyici bunları React'teki parçacıklara benzer şekilde otomatik olarak bir “parçacık” halinde gruplandırır. Ayrıca yapılarına ve kullanımlarına bağlı olarak belirli bayraklar da alırlar. Çoğu durumda çocuklarının sırası asla değişmez, ancak değişirlerse emri alırlar. "STABLE_FRAGMENT" Böylece çalışma zamanı herhangi bir öğe siparişi denetimini göz ardı edebilir.
Duyuru
![](https://Haberler.cloudimg.io/width/606/q50.png-lossy-50.webp-lossy-50.foil1/_Haber_/imgs/71/4/6/3/2/8/3/3/zander_timo-4ffc3ee7bcc71adb.jpg)
Timo Zander uygulamalı matematik ve bilgisayar bilimleri okudu ve yazılım geliştiricisi olarak çalışıyor. Açık kaynak, JavaScript evreni ve gelişen teknolojilerle ilgileniyor.
Bu güncellemeler hızla çok karmaşık hale gelebilir. Çerçevenin, mevcut görüntülenen HTML öğelerinin ve bileşenlerinin dayandığı önceki verilerle karşılaştırmak için yeni verilere dayalı yeni bir sanal DOM ağacı oluşturması gerekir. Saf bir uygulamada, çerçeve DOM'un tamamını yeniden oluşturabilir (aracılığıyla) document.innerHTML = "…") her zaman. Ancak bu, özellikle büyük web siteleri için son derece yavaş olacaktır. Bunun yerine, sanal DOM tabanlı çerçeveler, sanal DOM'un iki sürümü arasındaki, genellikle farklılık veya mutabakat olarak adlandırılan belirli farkları bulmaya çalışır.
Şekil 1'de gösterilen React uygulamasını düşünün. Her saniye, değişen zamanı görüntülemek için zaman ekranının yeniden oluşturulması gerekir. Kullanıcı adı girişi her değiştirildiğinde, uygulamanın bu bölümünün de değişen giriş değerini yansıtacak şekilde yeniden oluşturulması gerekir. Bu durumda diff prosedürü oldukça basittir: React'ın sanal DOM ağacını geçmesi ve iki yaprak bileşeninin durum farklılıklarını not etmesi gerekir. UsernameInput VE Time. Sonuç olarak DOM'un yalnızca bu iki küçük bölümünü yönetir. Daha büyük web siteleri için bu süreç giderek daha karmaşık hale gelebilir. Veri akışları daha karmaşık ve birbirine bağımlıdır, durum birçok bileşende yeniden kullanılabilir ve HTML öğelerinin toplam sayısı artar. Tüm bu koşullar, herhangi bir farklılaştırma algoritması için zorluk teşkil eder; bu nedenle, bu süreci hızlandırmak ve istikrarlı bir güncelleme hızı elde etmek için optimizasyonlara ve buluşsal yöntemlere ihtiyaç vardır. Bu stratejilerin bazıları Vue.js çerçevesinde uygulanmaktadır.
![Basit bir örnek uygulamanın sanal DOM ağacı (Şekil 1).](https://Haberler.cloudimg.io/width/696/q50.png-lossy-50.webp-lossy-50.foil1/_Haber_/imgs/18/4/6/3/2/7/6/2/fig1_example-982d51088abc696d.png)
Basit bir örnek uygulamanın sanal DOM ağacı (Şekil 1).
(Fotoğraf: Timo Zander)
Vue.js: çalışma zamanı ve derleyici birlikte çalışır
Vue.js, sanal DOM güncellemelerini işlemenin daha kesin bir yolunu uygular. Tek dosya bileşenleri (SFC) sayesinde çerçeve her zaman Vue.js kodunu standart JavaScript'e dönüştüren bir derleme aşamasına güvenmiştir. Ancak sözdizimini dönüştürmenin yanı sıra, derleyici aynı zamanda kodu analiz eder ve çalışma zamanının onu daha verimli bir şekilde yürütmek için kullanabileceği yapısı hakkında bilgi bırakır. Bu “derleyici bilgili sanal DOM” yaklaşımı, Vue.js'nin işleme performansının kıyaslama testlerinde düzenli olarak React'ı geçmesine olanak tanıyan şeydir. Örneğin, Vue.js, sanal DOM ağacının içinde statik HTML kodu parçaları bulduğunda, derleyici bunları oluşturma işlevinden kurtarır (Liste 1). Bu, site her değiştiğinde bu sanal düğümleri yeniden oluşturmak yerine çalışma zamanının her işleme için başlangıçta oluşturulan öğeleri yeniden kullandığı anlamına gelir. Çalışma zamanı, nesneleri yalnızca bir kez tahsis ederek, her işlemeden sonra kullanılmayan nesnelerin çöp toplama ihtiyacını ortadan kaldırır ve referans eşitliğini kullanarak öğeleri ayırt edebilir.
<div>
<div>foo</div> <!-- hoisted -->
<div>bar</div> <!-- hoisted -->
<div>{{ dynamic }}</div>
</div>
// Compiled:
const _hoisted_1 = /*#__PURE__*/_createElementVNode("div", null, "foo", -1 /* HOISTED */)
const _hoisted_2 = /*#__PURE__*/_createElementVNode("div", null, "bar", -1 /* HOISTED */)
export function render(_ctx, _cache, $props, $setup, $data, $options) {
return (_openBlock(), _createElementBlock("div", null, [
_hoisted_1,
_createCommentVNode(" hoisted "),
_hoisted_2,
_createCommentVNode(" hoisted "),
_createElementVNode("div", null, _toDisplayString(_ctx.dynamic), 1 /* TEXT */)
]))
}
Liste 1: Derlenmiş oluşturma işlevi, statik HTML öğeleri için sanal düğümleri yeniden oluşturmaz.
Vue.js yama bayrakları başka bir merkezi mekanizmadır. Bunlar, derleyicinin dinamik düğümlere atadığı ve çalışma zamanını bu düğümlerin nasıl değişebileceği konusunda bilgilendiren etiketlerdir: örneğin, bazı düğümler yalnızca stillerini değiştirebilir veya bir özelliğin değerini güncelleyebilirken diğerleri tamamen dinamik bir iç yapıya sahiptir. Kodu çalıştırdığınızda, çalışma zamanının yalnızca bir düğümün yama bayraklarına dayalı olarak belirli güncellemeleri ve kontrolleri gerçekleştirmesi gerekir.
Karşılaştırmayı hızlandırmak için bayraklar, bitsel yöntem kullanılarak karşılaştırılan bit maskeleri (Liste 2) olarak ifade edilir. AND Şebeke. Yama işaretleri, bir bileşenin değişebileceği tüm olası yolları kapsamaz ancak en yaygın durumları optimize etmeyi amaçlar. Örneğin, yalnızca dinamik metin içeriğine sahip düğümler (Dinamik div Liste 1'de) derleyiciye, düğümün çocuklarını (dizge olan) aşağıdaki yöntemi kullanarak karşılaştırmasını söyleyen bir bayrak alır eqeqeq operatöre başvurun ve gerekirse değiştirin.
export enum PatchFlags {
TEXT = 1, // 00000000000000000000000000000001
CLASS = 1 << 1, // 00000000000000000000000000000010
STYLE = 1 << 2, // 00000000000000000000000000000100
PROPS = 1 << 3, // 00000000000000000000000000001000
// ... more flags
}
Liste 2: Karşılaştırma performansını artırmak için yama bayrakları bit maskesi olarak saklanır.
Dinamik HTML nitelikleri de belirli bir bayrak alır: ortak varlıkları ve Vue.js'nin JavaScript nesnelerini bu nesnelere aktarmayı desteklemesi nedeniyle hem sınıf hem de stil niteliklerinin de özel bir bayrağı vardır. Derleyici, oluşturma işlevini oluşturmadan önce bu özelliklere ilişkin tüm girdileri nesnenin biçimine göre normalleştirir. Diğer donanımlar için Vue.js, dosyayı alan normal dinamik donanımları birbirinden ayırır. PROPS bayraklar ve yalnızca değerlerin değil, aynı zamanda donanımların da dinamik olduğu destekler; FULL_PROPS bayrak (Liste 3).
// Static props
<BlogPost title="Understanding the Vue compiler magic" /> >
// Static props with dynamic value
<BlogPost :title="title" /> >
// Dynamic props
const post = {
id: 1,
title: 'My Journey with Vue'
}
<BlogPost v-bind="post" />
Listeleme 3: Prop'lar dinamik değerlere sahipken statik olabileceği gibi tamamen dinamik de olabilir.
Vue.js, özelliklerin değişmediğini, yalnızca değerlerinin değiştiğini bildiğinde, bu aksesuarlar için eski ve yeni bileşenlerin değerlerini karşılaştırarak farkı hızlandırabilir. Ancak dinamik donanımlar, çalışma zamanının her iki bileşendeki mevcut tüm donanımları karşılaştırmasını gerektirir. React, Svelte ve Vue.js de dahil olmak üzere çoğu ön uç çerçevesi, kullanıcıların bir nesne listesi oluştururken bir öğe anahtarı belirtmesini de önerir. Anahtar kullanıldığında çalışma zamanı, olası değişiklikleri uygulamak için yeniden oluşturma öncesinde ve sonrasında aynı düğümü verimli bir şekilde tanımlayabilir. Aynı zamanda mevcut olmayan anahtarlar nedeniyle kaldırılan veya eklenen düğümleri sırasıyla yeni veya eski durumda hızlı bir şekilde bulabilir (Şekil 2). Bu anahtarlar dinamik bir listedeki bir düğümü benzersiz şekilde tanımlamak için kullanıldığından, kararlı ve benzersiz olmaları gerekir.
![Anahtarlar, dinamik olarak oluşturulmuş bir listede Vue.js çalışma zamanı farklarını daha verimli bir şekilde düzenlemenize olanak tanır (Şekil 2).](https://Haberler.cloudimg.io/width/696/q50.png-lossy-50.webp-lossy-50.foil1/_Haber_/imgs/18/4/6/3/2/7/6/2/fig2_list_diffing-8e8b8b20756d598e.png)
Anahtarlar, dinamik olarak oluşturulmuş bir listede Vue.js çalışma zamanı farklarını daha verimli bir şekilde düzenlemenize olanak tanır (Şekil 2).
(Fotoğraf: Timo Zander)
Üzerinde bulunduğu eleman "v-for" ifade bulunur ve ardından alır "KEYED_FRAGMENT" VEYA "UNKEYED_FRAGMENT" tuşların belirtilip belirtilmemesine bağlı olarak bayrak. Bu, çalışma zamanının, anahtarların en azından kısmen mevcut olduğuna güvenebileceğini bilmesi durumunda en iyi performans gösteren algoritmayı seçmesine olanak tanır. Üstelik, HOISTED VE BAIL Varsa her zaman bir öğenin tek bayrağı olan özel yama bayraklarıdır. Bu durumuda HOISTED flag'ı kullanarak çalışma zamanı, hiçbir zaman nemlendirilmesi gerekmeyen statik içeriği işaretlediğinden bileşen alt ağacını tamamen atlayabilir ve BAIL bayrağı, bir bileşenin optimize edilmemiş kaba kuvvet farkı algoritması kullanılarak işlenmesi gerektiğini belirtir.
Bu tür kaydetmeyi tetikleyen düğümler, genellikle kullanıcılar Vue.js'nin şablon derleyicisine güvenmek yerine bir işleme işlevini manuel olarak yazdıklarında oluşturulur, çünkü manuel işleme işlevleri herhangi bir yama bayrağı taşımaz. Bir Vue.js bileşeni birden fazla kök düğüme sahip olduğunda, derleyici bunları React'teki parçacıklara benzer şekilde otomatik olarak bir “parçacık” halinde gruplandırır. Ayrıca yapılarına ve kullanımlarına bağlı olarak belirli bayraklar da alırlar. Çoğu durumda çocuklarının sırası asla değişmez, ancak değişirlerse emri alırlar. "STABLE_FRAGMENT" Böylece çalışma zamanı herhangi bir öğe siparişi denetimini göz ardı edebilir.