What is Virtual DOM?

前端 未结 12 607
遥遥无期
遥遥无期 2020-11-28 01:39

Recently, I looked at Facebook\'s React framework. It uses a concept called \"the Virtual DOM,\" which I didn\'t really understand.

What is the Virtual DOM? What are

相关标签:
12条回答
  • 2020-11-28 02:16

    A virtual DOM(VDOM) is not a new concept: https://github.com/Matt-Esch/virtual-dom.

    VDOM is strategically to update DOM without redrawing all the nodes in a single page application. Finding a node in a tree structure is easy but the DOM tree for a SPA app can be drastically huge. Finding and updating a node/nodes in case of an event is not time efficient.

    VDOM solves this problem by creating a high level abstraction of actual dom. The VDOM is a high level lightweight in-memory tree representation of actual DOM.

    For example, consider adding a node in DOM; react keep a copy of VDOM in memory

    1. Create a VDOM with a new state
    2. Compare it with older VDOM using diffing.
    3. Update only different nodes in real DOM.
    4. Assign new VDOM as an older VDOM.
    0 讨论(0)
  • 2020-11-28 02:17

    What is the virtual DOM?

    The virtual DOM is an in-memory representation of the real DOM elements generated by React components before any changes are made to the page.

    It’s a step that happens between the render function being called and the displaying of elements on the screen.

    A component’s render method returns some markup, but it’s not the final HTML yet. It’s the in-memory representation of what will become real elements (this is step 1). Then that output will be transformed into real HTML, which is what gets displayed in the browser (This is step 2).

    So why go through all this to generate a virtual DOM? Simple answer — This is what allows react to be fast. It does this by means of virtual DOM diffing. Comparing two virtual trees — old and new — and make only the necessary changes into the real DOM.

    Source from Intro To React #2

    0 讨论(0)
  • 2020-11-28 02:20

    This is a brief description and reiteration of the Virtual DOM often mentioned alongside ReactJS.

    The DOM (Document Object Model) is an abstraction of structured text, which means it is made of HTML code and css. These HTML elements become nodes in the DOM. There are limitations to the previous methods of manipulating the DOM. Virtual DOM is an abstraction of the literal HTML DOM created well before React was created or used, but for our purposes we will use it in concert with ReactJS. The Virtual DOM is lightweight and detached from the DOM implementation in the browser. The Virtual DOM is essentially a screenshot (or copy) of the DOM at a given time. A way to look at it from a developers perspective is the DOM is the production environment and the Virtual DOM is the local (dev) environment. Each time the data changes in a React app a new Virtual DOM representation of the user interface is created.

    The most basic method needed in order to create a static component in ReactJS are:

    You must return code from the render method. You must convert every class to className since class is reserved word in JavaScript. Aside from the more major changes there are minor differences between the two DOMs including three attributes appearing in the Virtual DOM but not in the HTML DOM (key, ref and dangerouslySetInnerHTML).

    An important thing to understand when working with the Virtual DOM is the difference between ReactElement and ReactComponent.

    ReactElement

    • A ReactElement is a light, stateless, immutable, virtual representation of a DOM Element.
    • ReactElement - This is the primary type in React and resides in the Virtual DOM.
    • ReactElements can be rendered into HTML DOM

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

    • JSX compiles HTML tags into ReactElements

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

    ReactComponent

    • ReactComponent - ReactComponent's are stateful components.
    • React.createClass is considered a ReactComponent.
    • Whenever state changes the component is rerendered.

    Whenever a ReactComponent has a state change, we want as little change to the HTML DOM as possible so ReactComponent is converted to the ReactElement which can then be inserted to the Virtual DOM, compared and updated fast and easily.

    When React knows the diff - it's converted to the low-level (HTML DOM) code, which is executed in the DOM.

    0 讨论(0)
  • 2020-11-28 02:22

    According to React doc: https://reactjs.org/docs/faq-internals.html#what-is-the-virtual-dom

    'In React world, the term “virtual DOM” is usually associated with React elements since they are the objects representing the user interface. '

    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
           )
       }
    }
    
    

    The code inside return is actually a call to function React.createElement:

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

    which returns something like this:

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

    and this is virtual DOM. It's an JavaScript object which costs much less to manipulate than the actual DOM element created by

    document.createElement('button');
    

    which is also a JavaScript object looks like this:

    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
    

    You can learn more about virtual DOM and React at https://indepth.dev/inside-fiber-in-depth-overview-of-the-new-reconciliation-algorithm-in-react/

    0 讨论(0)
  • 2020-11-28 02:22

    let's make order and sense in this matter. React (or any other library) are a "layer" on javascript.

    There is no such thing as virtual dom, there is unattached dom .

    let me explain in simple javascript :

     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;
    

    at this point we have created a Div which is not shown on the dom , because it has not attached

    but we can access it, add attributes, values, change etc..

    once we call : (for ex,add it to body)

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

    then we will see it;

     for one how saw javascript libs come and go , i suggest to any one 
     to do one simple thing : master JAVAscript, not layers :)
    
    0 讨论(0)
  • 2020-11-28 02:23

    All the answers are great. I just came up with an analogy which probably can give a real-world metaphor.

    The real DOM is like your room, nodes are the furniture in your room. The virtual DOM is like we draw a blueprint of this current room.

    We all have the experience of moving furniture, it's very tiring (Same concept as updating views in computers). Therefore, whenever we want to change the position/add furniture (nodes), we want to only do the very necessary change.

    Blueprint came for the rescue to achieve it. We draw a new blueprint and compare the difference with the original one. This lets us know what part has been changed and what part stays the same. We then do the necessary change to the real room (update the changed nodes on the real DOM). Hurray.

    (Some might think, why do we have to rely on the virtual one and don't directly compare the real DOM? Well, in the analogy, comparing the real DOM means you have to create another real room and compare it with your original one. It's just too costly.)

    0 讨论(0)
提交回复
热议问题