I'm fresher from the non-IT field. I need to know about DOM and Virtual DOM? Please give me some examples.
The Document Object Model (DOM) is a cross-platform and language independent application programming interface wich treats an HTML, XHTML, or XML document as a tree structure wherein each node is an object representing a part of the document. The objects can be manipulated programmatically and any visible changes occurring as a result may then be reflected in the display of the document.
As others have stated the DOM -- Document Object Model -- is an object based representation of a website, used internally by browsers to keep track of style, layout, behaviors, and as a hook for JavaScript. Whilst it is initially built from HTML, and can be turned back into HTML, it tracks MORE than HTML generally would and can be an extremely powerful way of accessing the page's content and elements from JavaScript.
One of the most powerful and useful aspects of it is that for all intents and purposes the DOM is a "binary tree". Each DOM element contains four VERY important properties -- firstChild, lastChild, nextSibling, and previousSibling. You can use these to "walk the DOM" parsing through elements faster than creating various iterable array-like collections using the getElementsByWhatever methods.
Modern browsers add two more, nextElementSibling and previousElementSibling that point at elements - what HTML tags create. See, not all DOM nodes represent tags (ElementNodes), there are also textNodes (the text in the document), comment Nodes, and a host of other 'blocks'.
SADLY far, FAR too few developers realize this and typically end up slopping together for-next loops to do a DOM walks job.
Let's say you had a <ul id="mainMenu"> where you want to add a "mainMenuBlur" function as a 'onblur' handler to each and every LI. MOST developers using the dumbass (no offense guys) collection approach code it this way:
var mainMenuLi = mainMenu.querySelectorAll('#mainMenu > li');
for (var i = 0, iLen = mainMenuLi.length; i < iLen; i)) {
mainMenuLi[i].addEventListener('blur', mainMenuBlur, false);
}
This is actually surprisingly slow because JavaScript doesn't have TRUE arrays, it has pointered lists (under the hood) we PRETEND are arrays. If we were to walk the DOM:
var current = document.getElementById('mainMenu').firstElementChild;
if (current) do {
current.addEventListener('blur', mainMenuBlur, false);
} while (current = current.nextElementSibling);
This gets applied in a fraction the time as instead of having the LONG operation of querySelectorAll building the collection and the agonizingly slow (by comparison) array-like iteration, we just go from reference to reference through the direct children of the UL. (which should ALL be the LI). That's how you walk the DOM.
In Soviet Russia, the DOM walks you...
Additionally the DOM can be used to create/add/remove elements directly without even using HTML. The "innerHTML" method where people slop together strings of HTML to have JavaScript add stuff to the page? AVOID THAT! It's bloated, it's slow, it's often painful to work with, AND it can be a security risk if you aren't sanitizing anything you put into those strings that the user can create!
Let's say you wanted to add an LI with an anchor to the end of that menu. The innerHTML approach would be:
var mainMenu = document.getElementById('mainMenu');
mainMenu.innerHTML += '<li><a href="#disclaimer">Skip To Disclaimer</a></li>';
This LOOKS simple, but it isn't. It's slow. The entire DOM has to be parsed back into HTML, then have the string inserted in the appropriate place, then be parsed back into an all new DOM throwing away the old one. It's false simplicity in that it has 'simplified' the operation to the point it's no longer a good way of doing things. The DOM approach may be more code:
var
mainMenu = document.getElementById('mainMenu'),
newA = (
mainMenu.appendChild(document.createElement('li'))
).appendChild(document.createElement('a'));
newA.href = '#disclamer';
newA.appendChild(document.createTextNode('Skip To Disclaimer'));
But it runs many MANY times faster as by going straight to the DOM all the browser has to do is redraw the page... which isn't done until AFTER you release scripting execution. (we'll get to that again in a moment).
... and most of that code can be reduced in size by using helper functions, like my own elementals.js library's "_.make" method.
Which doing the above with elementals.js would look like this:
_.make('li', {
content : [ [ 'a@#disclaimer~Skip To Disclaimer' ] ],
last : document.getElementById('mainMenu')
});
Smaller than the innerHTML approach though it requires my framework to do so. My DOM-JON JSON format for doing this LOOKS similar to most "Virtual DOM" explanations, but is fundementally different in that I do NOT advocate using to maintain a second copy that you edit in addition to the live one.
As to the concept of a "virtual DOM"... well my opinion is not popular. It is entirely typical of what I've come to expect from "front end framework" mentality, hence it having originated with and being an 'essential part' of "react". It's a tissue of lies, disinformation, and ignorance used by people who don't understand JavaScript, its relationship to HTML, or how to use the bloody DOM properly. Literally the folks who created it either don't know enough about the DOM, or they intentionally are card-stacking their examples and explanations with garbage code to compare their disaster to.
An example of the unfounded claims you'll commonly hear is that changing many DOM elements in different parts of the code effects the render time as opposed to doing it as a 'batch' all at once... the problem is DIRECT changes to the DOM -- or using innerHTML for that matter -- do NOT get applied until you release JavaScript execution. As such so long as the script is 'running' any changes to the DOM are not applied to what the user sees!!!
... and we can test this!
cutcodedown.com/for_others/virtualDomIsBullshit
So that entire premise is based on 100% grade A farm fresh BULLSHIT!
In terms of card stacked cherry picked examples, they'll claim things like "when people want to remove one LI from a UL, they're rewrite ALL the LI" -- WHAT THE F%%%
Instead of saying "well don't do that" -- aka the PROPER answer -- they say to make a complete bloody "virtual copy" (wasting memory) to which you apply your changes, so those changes can be "batch applied" to the live browser DOM. (meaning you're doing it twice) HERPAFREAKINGDERP Then they have the giant set of donkey brass to say that's going to be FASTER?!?
If you know the LI you want to remove, JUST BLOODY REMOVE IT!!! Let's say we have a reference to the LI in a variable called "offendingLI"
offendingLi.parentNode.removeChild(offendingLi);
Uncle-huffing DONE! Removes JUST the one LI without touching anything else on the damned page. You don't have to rewrite the entire bloody UL and every single LI inside it!
Same goes for the mentally enfeebled claim that you "shouldn't be using the live DOM for tracking data" -- I've dealt with some jackasses who apply this mantra even when the section of DOM being manipulated is a bloody form... That's 100% grade A fictional trash that I have ZERO clue how or why anyone believes it! I can only assume that some 'name' in the industry flapped their arse-cheeks in the wind, and then the endless hord of putz out there parroted it endlessly.
EVERY one of the claims about how creating a Virtual DOM is faster, or simpler, or serves any legitimate purpose is unfounded nonsense...
Render doesn't take place until scripting ends, you CAN just remove an offending element. You CAN just attach elements directly from the DOM. The ONLY way you could see a benefit from it is if you're going full Pakled and using innerHTML where you shouldn't be using innerHTML! NONE of which has any negative impact on "render speed" or slows scripting execution -- the entire reason they claim to be doing it!
Admittedly, a LOT of off the shelf solutions (particularly "web services") are slopped together by people unqualified to write a single line of JavaScript, hence you being forced into derping innerHTML all over the place thanks to THEIR ineptitude.
Still, the whole "virtual DOM" idiocy is just part of why I reject asshat nonsense like React. Much like other so called "frameworks" it clearly is made not only for, but BY people who have zero damned business telling others how to build websites.
Hence why I do not call my own "library" a "framework". There is a fundamental difference in mindset and methodology.
Sometimes the stupid is so bad, it's agonizing to watch.
j
stuff ;)
as Leon Fiedler mentioned the DOM is basically the in memory representation of you HTML markup as objects.
the Virtual DOM is the Representation of the Markup in memory as well. one of the key differences is the Virtual DOM is not rendered.
The rise of the virtual DOM was basically the conclusion that the paint time - the time your browser takes to paint your interface - is bigger than the calculation time. So directly applying changes to the DOM all the time, is more costly than 1 batch update.
To track your changes, but only apply them once, the Virtual DOM will be merged with the next version of itself after the update. So only the differences will be applied and this leads to an overall better performance of the browser.
'Diff merge based'
Does this answer help you to understand the why?
As an example
//the virtual dom looks something like this { 'div' => { 'class': 'btn btn-primary'}} // which will be rendered to this <div class='btn btn-primary'></div> // so you add an id { 'div' => { 'class': 'btn btn-primary', 'id': 'foo'}} //what the virtual dom now does is only applying the difference between //the first and the second version which is the id <div id='foo' class='btn btn-primary'></div> // this is pretty basic but what if it happens 20 times? // so i send the command { 'div' => { 'class': 'btn btn-primary', 'id': 'foo'}} { 'div' => { 'class': 'btn btn-primary', 'id': 'foo'}} { 'div' => { 'class': 'btn btn-primary', 'id': 'foo'}} { 'div' => { 'class': 'btn btn-primary', 'id': 'foo'}} { 'div' => { 'class': 'btn btn-primary', 'id': 'foo'}} { 'div' => { 'class': 'btn btn-primary', 'id': 'foo'}} //these actually should never be applied.This is still far from optimal, but it was the trade of what is more costly: the paint or the calculation if it should be painted.
This is how I understand it and we could go into more detail .... but this a key point
Sai explained the virtual DOM in this article. hashnode.com/post/the-one-thing-that-no-one-prope…