I read through all the articles in internet. Still i cant understand and mind is puzzling me questions again and again that is
At the end of all the virtual DOM it is going to call the browser API to update the real DOM then how come it will be faster?
Is virtual DOM of React have special access to browsers core API's to modify?
I cant understand? Any resolves this questions Thanks in advance
Here is a talk given circa 2013 (v0.4.0) by the two guys behind React. They describe exactly how it works. Unlike data binding and dirty checking (Angular, etc.) React uses one render method that's called recursively. It then generates a long string that is a representation of the DOM. The concept is actually really simple.
https://www.youtube.com/watch?v=XxVg_s8xAms
Yes, you are right finally the task is to update real dom but the virtual dom comes in picture before updating the real dom. how ?
Suppose you want to update any/many element(s) in Dom tree element then there should be a mechanism to find which element(s) needs to be updated in real dom i.e the browser screen we see.
So this dom finding algorithm executed in virtual dom i.e a javascript copy of real dom(a html dom tree).
React creates two virtual dom, one from existing real dom and other from the changes made. These two virtual dom comparison saves time. The difference of this comparison used for updating real dom.
At the end of all the virtual DOM it is going to call the browser API to update the real DOM then how come it will be faster?
Any speed benefits come from minimizing the number of DOM manipulations that are needed and doing them all at once. The virtual DOM is react's way of calculating the minimum set of changes.
Here's what i mean by calculating the minimum set of changes: The page starts off looking one way, and then you want to make it look some other way. To get there, you're going to need to make one or more changes to the DOM, but there are many different ways you could do it.
A really bad way to update the page would be to wipe the entire document, and then rebuild every single element from scratch. Most likely though, you can reuse most of the page and just make a few updates to select parts of the page: add a div here; update a property there, add an event listener there. That's what you want: a small number of steps that take the old page and turn it into the new page.
Related
I know VDOM is just representation of real DOM which diffs with previous VDOM when some nodes have changed. But after all it is real DOM which going to take this output and repaint and redraw the screen, which is said to be dumb that it does not know how to change only the part of screen. I want to know how browser or real DOM differentiates that now I am dealing with VDOM and now with some regular stuff.
I want to know how browser or real DOM differentiates that now I am dealing with VDOM and now with some regular stuff.
The browser knows that you are doing some DOM stuff when you actually call methods on DOM objects (Node, Element, etc.).
DOM objects are totally separate from, and ignorant of, any Virtual DOM you might have in your code. Virtual DOM is really just a graph of regular JavaScript objects. There is nothing special at all about these objects. The fact that they supposedly represent part of a DOM document is known to us, but the browser couldn't care less; to it, it's just objects.
Diffing two Virtual DOM instances means finding the difference(s) in two object graphs. Again, from the browser's (or, more generally, the JavaScript execution environment's) perspective it's no different than diffing any other two JavaScript objects.
The resulting diff needs to be translated into DOM API calls. That is when the browser will realise that you're doing something to the DOM which might require reflowing & repainting the document on-screen.
How exactly Virtual DOM is faster than real DOM?
Virtual DOM per se does not have any speed. It's not slower, nor faster, than the DOM. It's simply an object. Modifying a Virtual DOM object graph is supposedly faster than modifying DOM objects because it will not immediately & automatically trigger reflow & repaints, so you can use the Virtual DOM as a "staging area" where you can prepare some future state of the DOM. Then when you're ready, use diffing to find the smallest number of changes that need to be applied to the DOM for the whole batch of changes you've made to the Virtual DOM since the last time.
(PS: If you're looking for raw speed, Virtual DOM as used in current frameworks (React, Vue.js, etc.) isn't your fastest option. See Rich Harris' talk at YGLF, "Rethinking reactivity" if you're curious.)
I am writing a little "fun" Scala/Scala.js project.
On my server I have Entities which are referenced by uuid-s
(inside Ref-s).
For the sake of "fun", I don't want to use flux/redux architecture but still use React on the client (with ScalaJS-React).
What I am trying to do instead is to have a simple cache, for example:
when a React UserDisplayComponent wants the display the Entity User with uuid=0003
then the render() method calls to the Cache (which is passed in as a prop)
let's assume that this is the first time that the UserDisplayComponent asks for this particular User (with uuid=0003) and the Cache does not have it yet
then the Cache makes an AjaxCall to fetch the User from the server
when the AjaxCall returns the Cache triggers re-render
BUT ! now when the component is asking for the User from the Cache, it gets the User Entity from the Cache immediately and does not trigger an AjaxCall
The way I would like to implement this is the following :
I start a render()
"stuff" inside render() asks the Cache for all sorts of Entities
Cache returns either Loading or the Entity itself.
at the end of render the Cache sends all the AjaxRequest-s to the server and waits for all of them to return
once all AjaxRequests have returned (let's assume that they do - for the sake of simplicity) the Cache triggers a "re-render()" and now all entities that have been requested before are provided by the Cache right away.
of course it can happen that the newly arrived Entity-s will trigger the render() to fetch more Entity-s if for example I load an Entity that is for example case class UserList(ul: List[Ref[User]]) type. But let's not worry about this now.
QUESTIONS:
1) Am I doing something really wrong if I am doing the state handling this way ?
2) Is there an already existing solution for this ?
I looked around but everything was FLUX/REDUX etc... along these lines... - which I want to AVOID for the sake of :
"fun"
curiosity
exploration
playing around
I think this simple cache will be simpler for my use-case because I want to take the "REF" based "domain model" over to the client in a simple way: as if the client was on the server and the network would be infinitely fast and zero latency (this is what the cache would simulate).
Consider what issues you need to address to build a rich dynamic web UI, and what libraries / layers typically handle those issues for you.
1. DOM Events (clicks etc.) need to trigger changes in State
This is relatively easy. DOM nodes expose callback-based listener API that is straightforward to adapt to any architecture.
2. Changes in State need to trigger updates to DOM nodes
This is trickier because it needs to be done efficiently and in a maintainable manner. You don't want to re-render your whole component from scratch whenever its state changes, and you don't want to write tons of jquery-style spaghetti code to manually update the DOM as that would be too error prone even if efficient at runtime.
This problem is mainly why libraries like React exist, they abstract this away behind virtual DOM. But you can also abstract this away without virtual DOM, like my own Laminar library does.
Forgoing a library solution to this problem is only workable for simpler apps.
3. Components should be able to read / write Global State
This is the part that flux / redux solve. Specifically, these are issues #1 and #2 all over again, except as applied to global state as opposed to component state.
4. Caching
Caching is hard because cache needs to be invalidated at some point, on top of everything else above.
Flux / redux do not help with this at all. One of the libraries that does help is Relay, which works much like your proposed solution, except way more elaborate, and on top of React and GraphQL. Reading its documentation will help you with your problem. You can definitely implement a small subset of relay's functionality in plain Scala.js if you don't need the whole React / GraphQL baggage, but you need to know the prior art.
5. Serialization and type safety
This is the only issue on this list that relates to Scala.js as opposed to Javascript and SPAs in general.
Scala objects need to be serialized to travel over the network. Into JSON, protobufs, or whatever else, but you need a system for this that will not involve error-prone manual work. There are many Scala.js libraries that address this issue such as upickle, Autowire, endpoints, sloth, etc. Key words: "Scala JSON library", or "Scala type-safe RPC", depending on what kind of solution you want.
I hope these principles suffice as an answer. When you understand these issues, it should be obvious whether your solution will work for a given use case or not. As it is, you didn't describe how your solution addresses issues 2, 4, and 5. You can use some of the libraries I mentioned or implement your own solutions with similar ideas / algorithms.
On a minor technical note, consider implementing an async, Future-based API for your cache layer, so that it returns Future[Entity] instead of Loading | Entity.
Can anyone explain the difference between the virtual DOM and the Real DOM in React JS? I got the below answer but it is still not clear to me. Any Help would be highly appreciated.
A virtual DOM is a lightweight JavaScript object which originally is just the copy of the real DOM. It is a node tree that lists the elements, their attributes and content as Objects and their properties. React’s render function creates a node tree out of the React components. It then updates this tree in response to the mutations in the data model which is caused by various actions done by the user or by the system.
Virtual DOM is very easy to understand if you take an example of a lift which has a mirror inside it. Suppose, 4 people enters into the lift. Now, the mirror will reflect its appearance with 4 people. Again people entering into the lift will reflect the object of mirror. And same effect happens when people exit from the lift, the mirror object gets changes (increase, decrease, or even empty). So, in reality mirror has no real object, but it only reflects its presence with outer object.
Virtual DOM is similar in concept. It has no real DOM. It is just a copy of real DOM wrapped in a JavaScript object. Whenever the DOM changes, virtual DOM also changes.
For your interest, you may see the following post:
Rendered element in react
While going through react I came up with the following doubts:
DOM operations are very expensive
But eventually react also does the DOM manipulation. We cannot generate a view with Virtual DOM.
Collapsing the entire DOM and building it affects the user experience.
I never did that, Mostly what I do is changing the required child node(Instead of collapsing entire parent) or appending HTML code generated by JS.
Examples:
As a user scrolls down we append posts to parent element, even react
also have to do it in same way. No one collapse entire dom for that.
When a user comment on a post we append a div(comment element(HTML code)) to that particular post comment list. I think no one collapse entire post(dom) for that
3) "diffing" algorithm to check changes:
Why we need a algorithm to check changes.
Example:
If I have a 100 posts, whenever a user clicks on edit button of a particular post, i do it as follows
$(".postEdit").click(function(){
var post_id = $(this).data("postid");
//do some Ajax and DOM manipulation to that particular post.
})
I am telling the DOM to change particular element, then how does diffing help?
Am I thinking in a wrong way? If so, please then correct me.
You are correct that people don't tend to collapse and recreate the entire DOM when they need to update a single element. Instead, the best practice is to just rebuild the element you need. But what if a user takes an action that actually impacts lots of elements? Like it they star a post or something, you want to reflect that on the post and maybe in a stars count elsewhere on the page. As applications get complex enough changing all of the parts of a page that need to be changed becomes really complicated and error prone. Another developer might not be aware that there is a "stars count" elsewhere on the page and would forget to update it.
What if you could just rebuild the entire DOM? If you wrote your render methods and stored your state such that at any point, you could with certainty render the entire page from scratch? That removes a lot of these pain points, but obviously you lose all the performance gains you got from manually altering parts of the DOM by hand.
React and the virtual dom give you the best of both worlds. You get that optimized DOM updating, but as a developer you don't have to keep a mental model of the entire application and remember what you need to change for any given user or network input. The virtual dom will also potentially implement these changes more effectively than you by literally only rebuilding the elements you need. At some point you might be rebuilding more than you should "just in case".
Hope this sort of makes sense!
This discussion can be very helpful to understand Virtual DOM and it's implementation in different UI frameworks.
Why is React's concept of Virtual DOM said to be more performant than dirty model checking?
There are couple of other links as well which explains it in better way.
https://auth0.com/blog/face-off-virtual-dom-vs-incremental-dom-vs-glimmer/
http://teropa.info/blog/2015/03/02/change-and-its-detection-in-javascript-frameworks.html
All:
I am pretty new to React.js, heard a lot about React virtual dom, but I kinda wondering what is the main difference between it and real DOM when deal with a simple case like change a style of a element:
Say I want to change the distance of a div to others, I can use jQuery for:
$("div#test").css("margin-left","10px");
And my understand about how browser does to the real dom is:
search down the DOM tree and find that node.
updating according style attribute( I guess it is CSSOM tree )
rendering the view
So my question is:
Is my understanding correct?
If it is basically correct, then what does virtual DOM do to improve the performance? Does not it just use a diff algorithm to compare what need to update in its light weighted version DOM tree and find that margin-left needs updating, and apply the same thing like in jquery to the real DOM?
OR
if it is not correct, could anyone give a little detail what heavy job does browser do to real DOM which React virtual DOM skip to enhance the performance?
I find a post mention 3 detail operation on virtual DOM:
What makes it really fast is:
Efficient diff algorithms.
Batching DOM read/write operations.
Efficient update of sub-tree only.
So comparing with this, does that mean in real DOM:
Not quite efficient diff algorithm or no diff algorithm(just update
everything)?
Single read/write operation like if I give 3 style updating to even same DOM element, the browser will look for that element down the DOM tree 3 times and update style?
Update whole DOM from the root(basically like dump the current tree and rebuild the whole DOM tree again no matter what part of the tree need update, and find the node and update)
Thanks
First of all, you are right with how the "real" DOM manipulation works.
React keeps an in-memory representation of the "real" DOM which we call the virtual DOM. Instead of traversing the "real" DOM for the node to modify, this virtual DOM is easily and quickly accessed therefore delivering update faster. Also, imagine a lot of changes in the DOM, traversing the "real" DOM would take a long time. This is one situation where the virtual DOM really excels.