Seriya: JavaScript Basics Dars 92

DOM va Virtual DOM

DOM va Virtual DOM farqi, nega DOM'ga tegish qimmat, ro'yxatlarda key muammosi va yechimi, diffing algoritmining taxminiy tabiati, V8'dagi obyekt yaratish narxi bilan DOM reflow/repaint narxini taqqoslash, va Virtual DOM har doim tez bo'lmasligi (Svelte misoli).

92-dars

DOM va Virtual DOM

Tasavvur qiling, sizda doska bor — unga siz rasm chizasiz, hamma ko'radi. Bu — DOM.

Endi tasavvur qiling, siz doskaga chizishdan oldin, qog'ozga qoralama chizasiz — hech kim uni ko'rmaydi, faqat siz uchun. Bu — Virtual DOM.

Nega qoralama kerak? Chunki doskaga chizish — sekin va zerikarli (o'chirish, qayta chizish vaqt oladi). Qog'ozga chizish — tez. Shuning uchun avval qog'ozda "rejalashtirib", keyin faqat kerakli joyni doskaga ko'chirasiz.


1. DOM — ekrandagi haqiqiy narsa

DOM — bu ekrandagi haqiqiy HTML:

<p id="son">5</p>

2. Virtual DOM — xotiradagi reja

Virtual DOM — bu oddiy JavaScript obyekti, ekranga hech qanday aloqasi yo'q:

{ tag: 'p', text: '5' }

Shu. Bu — faqat xotirada yashaydigan {} qavs, hech narsa chizmaydi.


3. Nega ikkitasi kerak — misol bilan

Sonni 5 dan 6 ga o'zgartiramiz.

To'g'ridan-to'g'ri DOM orqali:

document.getElementById('son').textContent = '6';

Bu ishlaydi, lekin — sahifada 100 ta shunday element bo'lsa, qaysi birini o'zgartirish kerakligini aniqlash qiyinlashadi.

Virtual DOM orqali — solishtirish usuli:

eski = { text: '5' }
yangi = { text: '6' }

if (eski.text !== yangi.text) {
  document.getElementById('son').textContent = yangi.text; // faqat farq bo'lsa tegamiz
}

G'oya: avval arzon narsani (JS obyektlarni) solishtiramiz, keyin faqat kerak bo'lgan joyga qimmat DOM orqali boramiz.

Aynan shu jarayonning o'zi — Reconciliation deb ataladi: yangi Virtual DOM bilan oldingi Virtual DOM'ni solishtirib, qaysi joylar o'zgarganini aniqlash jarayoni. React (va shunga o'xshash frameworklar) har bir render'da avval shu solishtirishni (reconciliation) o'tkazadi, so'ngra topilgan farqlarnigina haqiqiy DOM'ga qo'llaydi (bu qo'llash bosqichi — "commit" deb ataladi).


4. Nega DOM "qimmat", Virtual DOM "arzon"

DOM Virtual DOM
Nima u Ekrandagi haqiqiy element Xotiradagi oddiy {} obyekt
Tegish narxi Qimmat — brauzer qayta chizadi (reflow/repaint) Arzon — deyarli bepul
Nega qimmat/arzon Ranglar, o'lcham, joylashuv qayta hisoblanadi Faqat JS obyekt yaratish/o'qish

Brauzer bitta elementni o'zgartirganda, ko'pincha atrofidagi elementlarning joylashuvini ham qayta hisoblashi kerak bo'ladi. JS obyekti esa — sekundning millionidan bir qismida yaratiladi, hech qanday chizish yo'q.


5. Ro'yxatlar bilan muammo — murakkabroq holat

// Eski
['Olma', 'Behi', 'Uzum']

// Yangi — boshiga qo'shildi
['Anor', 'Olma', 'Behi', 'Uzum']

Agar dastur bularni indeks bo'yicha (0-o'rin bilan 0-o'rinni) solishtirsa:

0: 'Olma' → 'Anor'   → "Olma o'zgardi" (noto'g'ri!)
1: 'Behi' → 'Olma'   → "Behi o'zgardi" (noto'g'ri!)
2: 'Uzum' → 'Behi'   → "Uzum o'zgardi" (noto'g'ri!)
3: yo'q   → 'Uzum'   → "Uzum qo'shildi"

Dastur bularni 4 ta o'zgarish deb o'ylab, DOM'ga 4 marta tegadi — holbuki haqiqatda faqat 1 ta yangi element qo'shilgan, qolgani joyidan siljigan, xolos.


6. Yechim — key

Har bir elementga identifikator beriladi, indeksga emas, mazmunga bog'liq:

['Olma', 'Behi', 'Uzum'].map(meva => ({ key: meva, text: meva }))

Endi dastur key orqali taniydi: "Olma — hali bor, faqat joyi o'zgardi" deb, uni qayta yaratmaydi, faqat ko'chiradi. Faqat haqiqatan yangi bo'lgan Anor uchun yangi DOM elementi yaratiladi.

Muhim: key sifatida ro'yxat indeksini (0, 1, 2...) ishlatish — yomon odat, chunki element o'rni o'zgarsa, indeks ham o'zgaradi va key "yolg'on" ma'lumot beradi. key har doim ma'lumotning o'zidan kelishi kerak (masalan, item.id).


7. Chuqurroq — nima uchun bu "engineering" muammosi

Eng "to'g'ri" yechim — ikki ro'yxatni to'liq solishtirib, minimal farqni topish. Lekin bu matematik jihatdan juda sekin algoritm (O(n³)) — 1000 ta elementli ro'yxat uchun amalda ishlatib bo'lmaydi.

Shuning uchun React/Vue kabi frameworklar taxminiy, lekin tez qoida ishlatadi:

  • Faqat bir xil darajadagi (sibling) elementlar solishtiriladi
  • Tag turi boshqa bo'lsa — butunlay yangi deb hisoblanadi
  • key bor bo'lsa — Map orqali tez (O(n)) solishtiriladi

Bu — 100% matematik aniqlik emas, lekin amalda deyarli har doim to'g'ri ishlaydi, va tez.


8. V8 (brauzer motori) darajasida — nega bu ishlaydi

  • JS obyekt yaratish (Virtual DOM) — V8'ning eng tez xotira bo'limida (yosh avlod, Scavenger GC) bo'ladi, mikrosekundlar ichida yaratiladi va kerak bo'lmasa darhol tozalanadi.
  • DOM elementini o'zgartirish — brauzerning Layout → Paint → Composite bosqichlarini ishga tushirishi mumkin, bu millisekundlar, ba'zan o'nlab millisekundlar oladi.

Farq — o'nlab, hatto yuzlab marta. Shuning uchun strategiya: arzon JS hisoblashga ko'proq ish yuklab, qimmat DOM operatsiyasini minimal darajaga tushirish.


9. Muhim ogohlantirish — Virtual DOM har doim tez emas

Agar o'zgarish juda kichik va aniq bo'lsa (bitta <span> matnini yangilash), to'g'ridan-to'g'ri:

document.getElementById('x').textContent = yangi;

— bu Virtual DOM orqali (render → solishtirish → patch) o'tishdan tezroq, chunki oraliq obyekt yaratish va solishtirish shart emas. Shuning uchun Svelte kabi frameworklar Virtual DOM'ni umuman ishlatmaydi — ular build vaqtida aniq qaysi joy o'zgarishini bilib, to'g'ridan-to'g'ri kod yozib chiqaradi.


Yakuniy xulosa

  • DOM — haqiqiy, ekrandagi narsa, tegish qimmat.
  • Virtual DOM — xotiradagi reja, tegish deyarli bepul.
  • Strategiya: avval arzon rejalarni solishtir, faqat kerakli joyga qimmat DOM orqali bor.
  • Ro'yxatlarda key — kim kim ekanligini bilish uchun kerak, indeks emas, ma'lumot orqali.
  • Diffing algoritmi — matematik ideal emas, balki tez ishlaydigan taxminiy qoida.