What are the Virtual DOM, DOM, CSSOM, and the Critical Rendering Path?
This is my attempt to explain some of the programming concepts I have learned, I seek through this to test my understanding. If you find any incorrect information, please do point it out in the comments.
Today I am going to explain what is virtual DOM in react.
First, we must understand what is DOM and how HTML, CSS, and JS are rendered to the browser.
There is a process called “Critical Rendering Path” and the flow of this process goes like that:
1- HTML gets parsed into a tree of nodes (think of nodes as elements), each node consists of a value and this tree is called the DOM (Document Object Model).
so the following line of code:
The DOM representation of this single HTML element is going to look something like that: A node of h1 that holds inside of it a value
2- CSS also gets parsed into a tree of nodes called CSSOM (CSS Object Model)
so the following line of code:
will be parsed into this visual representation: A node of h1 that holds property
depending on where the JS file was requested in the HTML file, it will be executed, if you place it inside the head tag or in the middle or at the end of the HTML file then it will be executed as soon as it is received.
Therefore, it is important to place your JS script tag at the end of the HTML file just in case if the JS file depends on its execution on an element that might have not been parsed or rendered yet…Or you can add the “defer” or “async” attribute to the script tag to intentionally delay JS execution until the HTML parsing process is done.
An important note: both async and defer have some differences in terms of DOM events but it’s much better to just simply place the script tag before the body end tag.
4- Now the browser construct the render tree which is a combination of the DOM and CSSOM, and we have this representation of the render tree:
WAIT! before we get into how the render tree looks like, can you have a look at this piece of code and guess if it’s going to be added to the render tree?
Well…If you have guessed that span will NOT be added to the render tree, then you are right because the render tree only cares about what is visible.
This means if the div had a property display: none then both h1 and span won’t be added to the render tree.
And now the visual representation of this code should look like this:
I hope that you did notice that h1 inherited font-size property from its parent.
5- Layout stage where the browser evaluates what is the position of each element and how much width and height it will take…etc.
6- Paint stage where the browser paints the elements on the page.
Wow…you made it till this point? Impressive.
I will now start speaking about why the hell you should care to know about this CRP (Critical Rendering Path) thing.
This was important to understand why React introduced virtual DOM.
Let’s “metaphorically speaking” assume that we have a website like Facebook with millions of data being rendered to the page, what if a junior developer at Facebook decided to do something very simple such as changing text color. Can you imagine how extremely heavily this is going to be? Imagine that now the browser has to re-render millions of components and make thousands of requests and go through the flow of CRP from scratch again to parse HTML, CSS, and download JS Files and execute it then make judgments on which nodes on both DOM and CSSOM that should be inserted in the render tree?
THIS IS CRAZY! do you know how many lines of code Facebook source has since it started in 2004? Now imagine all of this has to be re-rendered again every time a change happens like someone changes the color of the text.
So what is the benefit of Virtual DOM?
It saves the day!
What React does under the hood is create a copy of the real DOM and store this copy in the memory and this is the “Virtual DOM” and whenever a change happens a new version of the Virtual DOM is created with the new updates applied to it.
Now we have 2 Virtual DOMS, one is the exact copy of the real DOM and the other one is the new version with the applied changes.
React does traverse through both trees (a DOM is a tree of nodes, remember?) and figure out the differences between them through a process or an algorithm called “The diff algorithm” AKA reconciliation.
Now, React kept track of which nodes got changed, and instead of re-rendering the entire real DOM, it will simply re-render the changed nodes.
The pros are obvious, you get to have faster performance, and re-painting flow won’t be costly on the performance or the server.