Ce este Virtual DOM? (Programare, Javascript, Reactjs)

Fizer Khan a intrebat.

Recent, m-am uitat la aplicația Facebook React de la Facebook. Acesta utilizează un concept numit „DOM virtual”, pe care nu l-am înțeles cu adevărat.

Ce este DOM virtual? Care sunt avantajele sale?

Comentarii

  • Cred că Virtual DOM se referă la nodurile care nu se află în DOM-ul normal. –  > Por Derek 朕會功夫.
  • Sunt de acord cu sentimentele de mai sus în ceea ce privește moderarea. În plus, cred că aceasta este o întrebare foarte valabilă și utilă. „DOM virtual” este adesea menționat, dar rareori definit. –  > Por btiernay.
  • @Rachael: Resursa la care ați făcut legătura nu conține cuvântul „Virtual DOM” și nu descrie beneficiul acestuia. Deci, acest lucru nu ajută cu adevărat la răspunsul la întrebarea OP. –  > Por blerontin.
13 răspunsuri
Chuck

React creează un arbore de obiecte personalizate care reprezintă o parte din DOM. De exemplu, în loc să creeze un element DIV real care conține un element UL, creează un obiect React.div care conține un obiect React.ul. Acesta poate manipula aceste obiecte foarte rapid fără a atinge DOM real sau a trece prin API-ul DOM. Apoi, atunci când redă o componentă, utilizează acest DOM virtual pentru a afla ce trebuie să facă cu DOM real pentru a face ca cei doi arbori să se potrivească.

Vă puteți gândi la DOM virtual ca la un plan. Acesta conține toate detaliile necesare pentru a construi DOM, dar pentru că nu necesită toate părțile grele care intră în componența unui DOM real, poate fi creat și modificat mult mai ușor.

Comentarii

  • Poate fi folosit pentru întregul DOM, în loc de doar o parte din el? –  > Por hipkiss.
  • Practic, este vorba de abstractizare peste abstractizare, ceea ce, în cele din urmă, ceea ce face react este să caute referința în arborele său de model de obiect, să selecteze nodul real din html și să se joace cu el. Sunetul este grozav virtual dom, , dar nu este nimic fantezist și exagerat. –  > Por syarul.
  • Ce vrei să spui prin „nu necesită toate piesele grele care intră într-un DOM real” – piese grele ?  > Por Ajay S.
  • @AjayS manipularea DOM real nu este foarte eficientă, de aceea se numește API grea. Manipularea obiectelor în memorie este mult mai rapidă și mai eficientă, actualizarea unei părți din DOM care s-a schimbat este, de asemenea, mai eficientă și mai rapidă. –  > Por jcubic.
  • Deci DOM virtual este mai rapid decât actualizarea DOM normal (nu în ceea ce privește React/Vue, ci doar în JS simplu)? –  > Por RealZombs.
user5341372

Să luăm un exemplu – deși unul foarte naiv: Dacă ai ceva încurcat într-o cameră din casa ta și trebuie să o cureți, care va fi primul pas? Vei curăța camera care este dezordonată sau întreaga casă? Răspunsul este cu siguranță că veți face curățenie doar în camera care necesită curățenie. Asta face DOM-ul virtual.

JS obișnuit traversează sau redă întregul DOM în loc să redea doar partea care necesită modificări.

Astfel, ori de câte ori aveți modificări, cum ar fi faptul că doriți să adăugați un alt <div> în DOM, atunci se va crea DOM virtual care, de fapt, nu va efectua nicio modificare în DOM-ul real. Acum, cu acest DOM virtual, veți verifica diferența dintre acesta și DOM-ul dvs. actual. Și numai partea care este diferită (în acest caz, noul <div>) va fi adăugată în loc să se redea întregul DOM.

Neri Barakat

Ce este DOM virtual?

DOM virtual este o reprezentare în memorie a elementelor DOM reale generate de componentele React înainte de a se face orice modificare a paginii.

Este un pas care se petrece între apelarea funcției de randare și afișarea elementelor pe ecran.

Metoda de randare a unei componente returnează niște marcaje, dar nu este încă HTML-ul final. Este o reprezentare în memorie a ceea ce va deveni elemente reale (acesta este pasul 1). Apoi, această ieșire va fi transformată în HTML real, care este ceea ce se afișează în browser (acesta este pasul 2).

Deci, de ce să treci prin toate acestea pentru a genera un DOM virtual?Răspuns simplu – Acest lucru permite ca reacția să fie rapidă. Aceasta se realizează prin intermediul diferențierii DOM virtuale. Compararea a doi arbori virtuali – vechi și nou – și efectuarea doar a modificărilor necesare în DOM-ul real.

Sursă din Introducere în React #2

Hitesh Sahu

A virtual DOM(VDOM) nu este un concept nou: https://github.com/Matt-Esch/virtual-dom.

VDOM este strategic pentru a actualiza DOM fără a redesena toate nodurile într-o aplicație cu o singură pagină. Găsirea unui nod într-o structură arborescentă este ușoară, dar arborele DOM pentru o aplicație SPA poate fi drastic de mare. Găsirea și actualizarea unui nod/nodurilor în cazul unui eveniment nu este eficientă din punct de vedere al timpului.

VDOM rezolvă această problemă prin crearea unei abstractizări de nivel înalt a DOM-ului actual. VDOM este o reprezentare arborescentă de nivel înalt și ușoară în memorie a DOM-ului real.

De exemplu, să considerăm adăugarea unui nod în DOM; reacționăm la păstrarea unei copii a VDOM în memorie

  1. Creați un VDOM cu o nouă stare
  2. Comparați-o cu VDOM mai vechi utilizând diffing.
  3. Actualizați numai nodurile diferite din DOM real.
  4. Atribuiți noul VDOM ca fiind un VDOM mai vechi.

Comentarii

  • etichetă înaltă sau nivel înalt? –  > Por Dushman.
esewalson

Aceasta este o scurtă descriere și o reiterare a DOM-ului virtual menționat adesea alături de ReactJS.

DOM (Document Object Model) este o abstractizare a textului structurat, ceea ce înseamnă că este alcătuit din cod HTML și css. Aceste elemente HTML devin noduri în DOM. Există limitări ale metodelor anterioare de manipulare a DOM. Virtual DOM este o abstractizare a DOM-ului HTML literal creat cu mult înainte ca React să fie creat sau utilizat, dar pentru scopurile noastre îl vom folosi împreună cu ReactJS. Virtual DOM este ușor și detașat de implementarea DOM din browser. Virtual DOM este, în esență, o captură de ecran (sau o copie) a DOM la un moment dat. Un mod de a privi acest lucru din perspectiva dezvoltatorilor este că DOM este mediul de producție, iar DOM virtual este mediul local (dev). De fiecare dată când datele se modifică într-o aplicație React, este creată o nouă reprezentare Virtual DOM a interfeței cu utilizatorul.

Cele mai de bază metode necesare pentru a crea o componentă statică în ReactJS sunt:

Trebuie să returnați codul din metoda render.Trebuie să convertiți fiecare clasă în className, deoarece class este un cuvânt rezervat în JavaScript.În afară de schimbările mai importante, există diferențe minore între cele două DOM-uri, inclusiv trei atribute care apar în DOM Virtual, dar nu și în DOM HTML (key, ref și dangerouslySetInnerHTML).

Un lucru important de înțeles atunci când se lucrează cu Virtual DOM este diferența dintre ReactElement și ReactComponent.

ReactElement

  • Un ReactElement este o reprezentare virtuală ușoară, fără stare, imuabilă și imuabilă a unui element DOM.
  • ReactElement – Acesta este tipul principal în React și locuiește în DOM virtual.
  • ReactElements pot fi redate în DOM HTML

    var root = React.createElement('div');
    ReactDOM.render(root, document.getElementById('example'));

  • JSX compilează etichetele HTML în ReactElements

    var root = <div/>;
    ReactDOM.render(root, document.getElementById('example'));

ReactComponent

  • ReactComponent – ReactComponent sunt componente cu stare.
  • React.createClass este considerat un ReactComponent.
  • Ori de câte ori se schimbă starea, componenta este redată din nou.

Ori de câte ori un ReactComponent are o schimbare de stare, dorim o modificare cât mai mică a DOM-ului HTML, astfel încât ReactComponent este convertit în ReactElement, care poate fi apoi inserat în DOM-ul virtual, comparat și actualizat rapid și ușor.

Când React cunoaște diferența – este convertit în cod de nivel scăzut (HTML DOM), care este executat în DOM.

laksys

Este un concept frumos: în loc să manipulați direct DOM, care este predispus la erori și se bazează pe o stare mutabilă, în schimb scoateți o valoare numită DOM virtual. DOM virtual este apoi diffed cu starea actuală a DOM, ceea ce generează o listă de operațiuni DOM care ar face ca DOM-ul actual să arate ca cel nou. Aceste operații sunt aplicate rapid într-un lot.

Preluat din aici.

Nikhil

Virtual DOM este o abstractizare a DOM HTML care redă selectiv subarcuri de noduri în funcție de schimbările de stare. Acesta face cea mai mică cantitate posibilă de manipulare DOM pentru a vă menține componentele la zi.

Comentarii

  • Ce are de-a face cu abstractizarea ? cuvântul abstractizare este irelevant aici –  > Por eladcm.
mansi joshi

DOM virtual este creată o copie a Dom. Dom virtual este comparat cu dom, iar domul virtual actualizează doar acea parte din dom care s-a schimbat. Nu se redă întregul dom, ci doar partea actualizată a domului din dom. Este foarte consumator de timp, iar din această funcționalitate, aplicația noastră funcționează rapid.

KunYu Tsai

Toate răspunsurile sunt excelente. Tocmai am venit cu o analogie care, probabil, poate oferi o metaforă din lumea reală.

DOM real este ca o cameră, nodurile sunt mobilierul din cameră. DOM-ul virtual este ca și cum am desena o schiță a acestei camere actuale.

Cu toții avem experiența mutării mobilei, este foarte obositor (Același concept ca și actualizarea vizualizărilor în calculatoare). Prin urmare, ori de câte ori dorim să schimbăm poziția/adăugăm mobilier (noduri), dorim să facem doar modificarea foarte necesară.

Blueprint a venit în ajutor pentru a realiza acest lucru. Desenăm un nou blueprint și comparăm diferența cu cel original. Acest lucru ne permite să știm ce parte a fost modificată și ce parte rămâne la fel. Apoi, efectuăm modificările necesare în camera reală (actualizăm nodurile modificate în DOM-ul real). Ura.

(Unii s-ar putea gândi, de ce trebuie să ne bazăm pe cel virtual și nu comparăm direct DOM-ul real? Ei bine, în analogie, compararea DOM real înseamnă că trebuie să creați o altă cameră reală și să o comparați cu cea originală. Este pur și simplu prea costisitor).

Koushik Pan

Unitatea structurală a lui React este componenta. Fiecare componentă are o stare. Ori de câte ori se schimbă starea unei componente, React modifică arborele V-DOM. Ulterior, ultima versiune a V-DOM este comparată cu versiunea anterioară a V-DOM. După acest calcul (diferențiere), atunci când React știe ce obiecte V-DOM au fost modificate, modifică numai acele obiecte din R-DOM.

În termeni simpli,

Să spunem că am adăugat un element div în DOM, React creează o copie a V-DOM fără a modifica întregul R-DOM. Acest V-DOM nou creat este comparat cu V-DOM mai vechi. Se actualizează doar nodurile diferite din DOM real. Acum, V-DOM-ul nou creat este considerat versiunea anterioară pentru V-DOM-ul următor.

P.S. 1. Astfel, spre deosebire de plain js, este creată o versiune complet nouă a V-DOM și R-DOM este parțial actualizat. 2. React nu actualizează fiecare schimbare de stare, ci actualizările către R-DOM sunt trimise în loturi.

Ahamed Safnaj

React păstrează o reprezentare ușoară a DOM real în memorie, iar aceasta este cunoscută sub numele de DOM virtual. Atunci când se schimbă starea unui obiect, DOM virtual modifică doar acel obiect din DOM real, în loc să actualizeze toate obiectele.

Carnea de caramel Conmigo

Conform documentului React: https://reactjs.org/docs/faq-internals.html#what-is-the-virtual-dom

‘În lumea React, termenul „DOM virtual” este de obicei asociat cu elementele React, deoarece acestea sunt obiectele care reprezintă interfața cu utilizatorul. ‘

import React, { Component } from 'react'; //You need to do this inside a module to import

class App extends Component{
   render(){
       return (
       <button>Hi</button> //This returns a virtual DOM
       )
   }
}

Codul din interiorul return este de fapt un apel la funcția React.createElement:

//render can be rewritten like this:
render(){
   return [
            React.createElement(
                'button',
                {
                    key: null,
                    ref: null,           
                },
                'Hi',
            )
   ]
}

care returnează ceva de genul acesta:

{
  $$typeof: Symbol.for('react.element'), 
  type: "button", 
  key: null, 
  ref: null, 
  props: { 
     children: 'Hi',
  }
}

și acesta este DOM virtual. Este un obiect JavaScript care costă mult mai puțin să fie manipulat decât elementul DOM real creat de către

document.createElement('button');

care este, de asemenea, un obiect JavaScript arată astfel:

accessKey: ""
ariaAtomic: null
ariaAutoComplete: null
ariaBusy: null
ariaChecked: null
ariaColCount: null
ariaColIndex: null
ariaColSpan: null
ariaCurrent: null
ariaDescription: null
ariaDisabled: null
ariaExpanded: null
ariaHasPopup: null
ariaHidden: null
ariaKeyShortcuts: null
ariaLabel: null
ariaLevel: null
ariaLive: null
ariaModal: null
ariaMultiLine: null
ariaMultiSelectable: null
ariaOrientation: null
ariaPlaceholder: null
ariaPosInSet: null
ariaPressed: null
ariaReadOnly: null
ariaRelevant: null
ariaRequired: null
ariaRoleDescription: null
ariaRowCount: null
ariaRowIndex: null
ariaRowSpan: null
ariaSelected: null
ariaSetSize: null
ariaSort: null
ariaValueMax: null
ariaValueMin: null
ariaValueNow: null
ariaValueText: null
assignedSlot: null
attributeStyleMap: StylePropertyMap {size: 0}
attributes: NamedNodeMap {length: 0}
autocapitalize: ""
autofocus: false
baseURI: "http://localhost:3000/"
childElementCount: 0
childNodes: NodeList []
children: HTMLCollection []
classList: DOMTokenList [value: ""]
className: ""
clientHeight: 0
clientLeft: 0
clientTop: 0
clientWidth: 0
contentEditable: "inherit"
dataset: DOMStringMap {}
dir: ""
disabled: false
draggable: false
elementTiming: ""
enterKeyHint: ""
firstChild: null
firstElementChild: null
form: null
formAction: "http://localhost:3000/"
formEnctype: ""
formMethod: ""
formNoValidate: false
formTarget: ""
hidden: false
id: ""
innerHTML: ""
innerText: ""
inputMode: ""
isConnected: false
isContentEditable: false
labels: NodeList []
lang: ""
lastChild: null
lastElementChild: null
localName: "button"
name: ""
namespaceURI: "http://www.w3.org/1999/xhtml"
nextElementSibling: null
nextSibling: null
nodeName: "BUTTON"
nodeType: 1
nodeValue: null
nonce: ""
offsetHeight: 0
offsetLeft: 0
offsetParent: null
offsetTop: 0
offsetWidth: 0
onabort: null
onanimationend: null
onanimationiteration: null
onanimationstart: null
onauxclick: null
onbeforecopy: null
onbeforecut: null
onbeforepaste: null
onbeforexrselect: null
onblur: null
oncancel: null
oncanplay: null
oncanplaythrough: null
onchange: null
onclick: null
onclose: null
oncontextmenu: null
oncopy: null
oncuechange: null
oncut: null
ondblclick: null
ondrag: null
ondragend: null
ondragenter: null
ondragleave: null
ondragover: null
ondragstart: null
ondrop: null
ondurationchange: null
onemptied: null
onended: null
onerror: null
onfocus: null
onformdata: null
onfullscreenchange: null
onfullscreenerror: null
ongotpointercapture: null
oninput: null
oninvalid: null
onkeydown: null
onkeypress: null
onkeyup: null
onload: null
onloadeddata: null
onloadedmetadata: null
onloadstart: null
onlostpointercapture: null
onmousedown: null
onmouseenter: null
onmouseleave: null
onmousemove: null
onmouseout: null
onmouseover: null
onmouseup: null
onmousewheel: null
onpaste: null
onpause: null
onplay: null
onplaying: null
onpointercancel: null
onpointerdown: null
onpointerenter: null
onpointerleave: null
onpointermove: null
onpointerout: null
onpointerover: null
onpointerrawupdate: null
onpointerup: null
onprogress: null
onratechange: null
onreset: null
onresize: null
onscroll: null
onsearch: null
onseeked: null
onseeking: null
onselect: null
onselectionchange: null
onselectstart: null
onstalled: null
onsubmit: null
onsuspend: null
ontimeupdate: null
ontoggle: null
ontransitionend: null
onvolumechange: null
onwaiting: null
onwebkitanimationend: null
onwebkitanimationiteration: null
onwebkitanimationstart: null
onwebkitfullscreenchange: null
onwebkitfullscreenerror: null
onwebkittransitionend: null
onwheel: null
outerHTML: "<button></button>"
outerText: ""
ownerDocument: document
parentElement: null
parentNode: null
part: DOMTokenList [value: ""]
prefix: null
previousElementSibling: null
previousSibling: null
scrollHeight: 0
scrollLeft: 0
scrollTop: 0
scrollWidth: 0
shadowRoot: null
slot: ""
spellcheck: true
style: CSSStyleDeclaration {alignContent: "", alignItems: "", alignSelf: "", alignmentBaseline: "", all: "", …}
tabIndex: 0
tagName: "BUTTON"
textContent: ""
title: ""
translate: true
type: "submit"
validationMessage: ""
validity: ValidityState {valueMissing: false, typeMismatch: false, patternMismatch: false, tooLong: false, tooShort: false, …}
value: ""
willValidate: true

Puteți afla mai multe despre DOM virtual și React la adresa https://indepth.dev/inside-fiber-in-depth-overview-of-the-new-reconciliation-algorithm-in-react/

eladcm

haideți să facem ordine și sens în această chestiune. React (sau orice altă bibliotecă) sunt un „strat” pe javascript.

Nu există un astfel de lucru ca dom virtual, există dom neatașat .

permiteți-mi să vă explic în javascript simplu :

 let vDom = {};     // this is a object that will be used to hold the elements

 let d = document.createElement('div');
 d.innerHTML = 'hi, i am a new div';

 vDom['newDiv'] = d;

în acest moment am creat un Div care nu este afișat pe dom , deoarece nu este atașat.

dar putem să-l accesăm, să adăugăm atribute, valori, să modificăm etc..

odată ce apelăm: (de exemplu, adăugăm la corp)

    document.body.appendChild(vDom['newDiv'])

atunci îl vom vedea;

 for one how saw javascript libs come and go , i suggest to any one 
 to do one simple thing : master JAVAscript, not layers :)

Comentarii

  • „Nu există un domeniu virtual” – Există. Este o caracteristică de bază a modului în care funcționează React. Răspunsul acceptat la această întrebare o explică destul de bine. –  > Por Quentin.
  • Răspunsul tău descrie de fapt un DOM real. DOM-ul real există după ce apelați document.createElement, nu contează dacă a fost adăugat sau nu. –  > Por Toffee Conmigo.