Search code examples
reactjsvirtual-dom

How React virtual dom differ from to Ajax in functionality?


I just started to learn React JS. Learnt how react updates changes on render, how virtual dom helps to do it. I'm a dev who used ajax previously on projects. I understood the benefits and efficiency of using React. But while learning I understood that react virtual dom is being used to update only the objects which have changes. If I am not mistake, same thing is achieved by Ajax. Someone clear both concepts.


Solution

  • Let us separate context into three items;

    1. Internet
    2. Communication
    3. Content (HTML JS and CSS)
    4. Browser

    It is of common knowledge that;

    • we need Browser to view content.
    • Browser communicate via HTTP protocol via internet

    It is high likely you have heard of Document Object Model (DOM) however there is another aspect known as Browser Object Model (BOM). It is BOM which;

    1. takes your URL from address bar or anchor link you click on then fetches concerned content and forwards it to DOM for interpretation.
    2. Once the new content is received by DOM, it interprets the code and draws meaningful visual representation.
    3. This interpretation cycle is denoted by various window states and event i.e. pop, document ready, on page show, on page hide, on load, on unload, on resize, on focus, on click etc.

    Some diagrams for better under standing, please take some time to glean at them.

    Window, BOM, DOM and Javascript relationship

    Document Object Model Node Tree

    Browser Object Model

    Relationship of JavaScript with JavaScript coding standards, DOM and BOM

    Scheme of things work as following;

    1. URL fetched - pop event

    2. Initial HTML code received - document ready state

    3. HTML code interpreted, kept in memory associated with that particular window as DOM Tree state- window rendered event

    4. Visual representation as result of rendering pushed to screen - on page show event

    5. DOM tree drawn on screen pixel by pixel - window painted event

    6. Meanwhile all other associated content is being fetched e.g. CSS, JS, background images etc.

    7. Associated content is fully received - on load event

    8. on completion of on load event newly received CSS & JS compared with the state kept in associated memory as in step 3.

    9. If there are differences, or new instructions start over from step 3.

    In nutshell;

    • we are rendering and painting window twice for single collective page.
    • We do not notice it much these days because browser memory has improved other wise the good old days white flash or flicker was an impact of such state and events.
    • Matter only becomes worse if we need to hop from one page to another. First browser must call on pop event, then page hide, then on before unload event then start all over from step 2 doing every thing twice.
    • To really run stem in developers brain, DOM standards aka HTML standards are maintained by W3C,JavaScript standards are maintained ECMA, browser are stipulated as what and which standards they choose to include in BOM. Thus while tag might work in all others may not work in IE or while arrow function may work in modern browsers may not work in slightly older version of browsers. That is why we use polyfills, and precisely why various libraries and frame works exist, including JQuery.

    What Ajax intends to achieve?

    Once the browser enters into document ready state BOM instructs navigator functionality to initiate number of HTTP connections (may be up to 6 at a time) in order to download various images, CSS and JS files embedded in the page. This all then goes on in the background.

    Developers hate IE due to its notorious ways of not implementing latest DOM or JS features in BOM. However if it was not for IE we would not have AJAX as we now it.

    In 1996 IE introduced iframe feature which could download external content in that particular area of page. Any subsequent HTTP request would be repainted in that particular area of screen rather then repainting whole page. Novel idea was simple as to use the same scheme of things one uses for downloading images, for iframe. Obviously it had to be implemented at BOM level. So IE5 onward iframe tag became standard feature. Within a year iframe was introduced as standard in HTML 4.0 DOM standard, all the browsers implemented the technique in their BOM as default.

    By 1999 novel idea of communicating behind the scene after document ready state, led to a further "what if?" notion. What if using JavaScript we could fetch any content like iframe and update any given area on the screen. Again IE was the one to come up with the solution known as XMLHTTP ActiveX control. Shortly afterwards Mozilla, Safari, Opera and other browsers later implemented it as the XMLHttpRequest JavaScript object. Again its BOM feature, and probably why you had to write this code.

        function Xhr(){ /* returns cross-browser XMLHttpRequest, or null if unable */
        try {
            return new XMLHttpRequest();
        }catch(e){}
        try {
            return new ActiveXObject("Msxml3.XMLHTTP");
        }catch(e){}
        try {
            return new ActiveXObject("Msxml2.XMLHTTP.6.0");
        }catch(e){}
        try {
            return new ActiveXObject("Msxml2.XMLHTTP.3.0");
        }catch(e){}
        try {
            return new ActiveXObject("Msxml2.XMLHTTP");
        }catch(e){}
        try {
            return new ActiveXObject("Microsoft.XMLHTTP");
        }catch(e){}
        return null;
    }
    

    Thank you my dear lord for giving John Resig the courage to develop JQuery which made AJAX as easy as a whistle.

    What did we achieve from AJAX?
    PROS

    • We conducted communication through document level Navigator instance through JS programming reference diagram 3 of BOM, rather than window level navigator event reference diagram 1 of Window, BOM, DOM and Javascript relationship.
    • After re-rendering of DOM tree repainting only the part of DOM tree in concern rather than redrawing whole DOM tree aka repainting whole page. Hence no white flicker.
    • Post re-rendering we could traversal and manipulation the new content as if it was part of the original content.
    • We could trigger up to six of these navigator instances that would run asynchronously, following the above pattern independent of each other as detailed above.

    CONS

    • Since there is no window level navigator event BOM does not call on history function. Hence no pop state, thus most likely no cache and definitely no URL change in address bar.
    • To avail any of these missing functionalities one would have to instance them programminglly. Default is no action.

    What React intends to achieve?

    Since the advent of AJAX, scalable web applications began to emerge. This in contrast to web page. Single Page Application (SPA) is just another name for the same context. SPA as concept soon lead to AJAX based web component development e.g. AJAX form submission, auto complete and that colour changing message bell and what not.

    Referring back to DOM, every time we receive initial HTML code as window pop event, DOM parser goes through the code from top line towards bottom line. Once passed the line it will not go back up again. On each passing of the line it parses the line and adds it to then being rendered DOM tree which will be painted latter. Example as following;

    <!DOCTYPE html>
    <html>
    <body>
    
    <h1>My First Heading</h1>
    <p>My first paragraph.</p>
    
    </body>
    </html>
    

    Parser reads first tag to determine what standard to follow, then once it comes to body tag it applies default properties of that element, then h1 tag applies default properties if non declared explicitly. Default properties are defined by W3C in HTML 5 standards.

    Now we have DOM tree rendered in memory has to be painted on to screen. This is where fun begins. Referring back to 4th diagram relationship of JavaScript with ECMA, DOM and BOM. BOM calls on JS engine to do the Picasso work on screen.

    This in short is called;

    • Hard DOM - one which is received initially via pop event
    • Virtual DOM - one which is parsed and comprises of DOM tree in memory
    • HARD DOM - again which will be painted on to screen from virtual DOM
    • Shadow DOM - certain element of DOM tree have fixed behaviour and properties that are once implemented are called shadow DOM of that particular DOM tree element.

    Shadow DOM example

    <input type="text" name="FirstName" value="Mickey"></input>
    

    Has shadow DOM applied as following;

    <input type="text" name="FirstName" value="Mickey">
    #shadow-root (user-agent)
    <div>Mickey</div>
    </input>
    

    Aha so input is probably actually is an editable div after all. Now you know what contenteditable="true" property is does on div tag.

    So scheme of things are as following;

    1. HTML code is received
    2. HTMl is parsed into Virtual DOM
    3. Parallel to which Shadow DOM is applied on each of the concerned tree items
    4. Both virtual and Shadow DOM are kept in memory
    5. Both of them get painted on to screen collectively as flattened HARD DOM tree.

    We have easy traversal access to HARD DOM and Virtual DOM but accessing shadow DOm is whole new ball game. So we leave it to that.

    This is how it pans out in following diagram; HTML parsing to paint journey

    While at latter stage JS engine runs batch of commands and creates object identifier of each item rendered in virtual DOM tree. Below is just an example if you were to create it your self.

    var btn = document.createElement("BUTTON");   
    btn.innerHTML = "CLICK ME";                   
    document.body.appendChild(btn);
    

    Once the create element function is called virtual DOM has another element rendered into it. You can then do what ever you wish with it.

    However until you call append child it never enters the territory of HARD flattened DOM. Then again you can do what ever you wish to do with after it enters Hard DOM.

    So whats the point of all Virtual and Hard DOM?

    Lets explore. In normal scheme of things if I was to traversal hard DOM I would have to query the current document to run through all its DOM tree and find the element we are looking for. This is what Jquery does, result is called HTML collection. Example below;

    var btn = document.createElement("BUTTON");   
    btn.innerHTML = "CLICK ME";                   
    document.body.appendChild(btn);
    // manipulate for the created element via hard DOM way but first find it
    document.querySelector("BUTTON").innerHTML = "OPPS ME";
    

    Suppose there are 5 buttons then which button will above query manipulate. Just the first one.

    To manipulate the 3rd one only I need to first generate HTML collection into array then run through that array to find reference for my desired element then manipulate it. Example below;

    document.querySelectorAll("BUTTON")[2].innerHTML = "OPPS ME";
    

    That is lot of leg work just to change the text of one button. If I wish to do it virtual way all I had to do was call on this code;

      btn.innerHTML = "OPPS ME";
    

    React intends to do the virtual way.

    • It dictates there will be no initial HARD DOM HTML code. Just JS in body tag if at all.
    • It runs batch of jS create element functions to generate DOM tree and creates a reference to newly created element.
    • Once the whole tree is generated it pushes it for painting.
    • In doing so cutting the leg work for parsing and then rendering then painting then re-parsing then re-rendering then repainting.
    • When in future some thing needs to be updated it calls on the reference and does the magic work as we did.
    • Browser BOM by default always keeps in sync the virtual DOM to hard DOM and hard DOM to virtual DOM. If one thing changes in any one of them it is reflected in the other as mirror depiction.
    • Whats more if you can keep record of what you changed and on what reference, you can go back and forth in implementing and re-implementing them as if they are cached in history.
    • BOM already does that on form inputs Ctrl+Z, Ctrl+Y. Only in react you are doing it through JS on all of the elements. This my friend is the very basic of state management.

    What did we achieve from React?

    PROS

    • saved time and headache in parsing, rendering, painting, finding, manipulating DOM tree.

    • In doing so only repainting the part of DOM tree in concern rather than redrawing whole DOM tree aka repainting whole page. Hence no white flicker similar to AJAX.

    • One can perform pre-render calculations on data beforehand, only do actions if conditions meet.

    • You control the state management.

    CONS

    1. No pop state, thus have to engage in programming to avail such features.
    2. One has to build routing system or simple F5 sends you back to step one as if nothing ever existed.
    3. Heavy reliance on JS, almost forgoing the brilliant potential DOM environment can offer, CSS etc are just step siblings.
    4. SPA Notion is almost a decade old, it has since then been realised it does not fix all problems. Modern mobile environment requires more.
    5. End script is bloated.

    What React does not care about?

    React does not care how the new data comes and where from. Be it ajax, be user fed, all it does is manage state of data e.g.old button text was "so and so" new data is "so and so" should the change be made or not. If change is made keep a record of it.

    Both react and Ajax intend to leech on BOM processes, and initiate functions in light of progressive enhancement and user experience.

    One does it by manipulating how communication is made other does it by how data from communication is rendered in the end.

    Thus both are essentially part of SPA concept, may compliment each other but function interdependently in two different domains.