Difference between incremental DOM and virtual DOM in Angular - javascript

I have two questions regarding angular. I've tried reading some articles but I can't get the idea,
What is incremental DOM?
what is the difference between incremental DOM and virtual DOM?

Incremental DOM is a library for building up DOM trees and updating them in-place when data changes. It differs from the established virtual DOM approach in that no intermediate tree is created (the existing tree is mutated in-place). This approach significantly reduces memory allocation and GC thrashing for incremental updates to the DOM tree therefore increasing performance significantly in some cases.
https://github.com/google/incremental-dom
Virtual DOM compares (diff) a new entire virtual DOM with the previous virtual DOM for changes then applies those changes to the actual DOM. - This approach creates a new virtual DOM to determine the changes (memory heavy).
Incremental DOM has one virtual DOM and walks along the tree to find changes then mutates the virtual DOM and then apply those changes to the actual DOM - (reduced memory size and garbage collection).
Virtual DOM - has a big memory footprint because it needs headroom for changes that "might" happen to the virtual DOM.
Incremental DOM - doesn’t need such a big footprint as memory is only allocated for changes.
Tests have shown that Incremental DOM is fast enough to work even without a virtual DOM also.

Related

Is the DOM stored in ram normally or in heap memory?

I'm confused about the JavaScript data structure. I know that JavaScript uses the stack and heap memory data structure, but I don't understand why a very large DOM causes crashes, but if I just add a large video on the page, for example, the DOM is still light. Videos and audios are outside the stack and heap memory? if the question is confusing, I'm sorry, but I don't understand how I can load a 2GB video on a page, for example, and not run out of limited JavaScript memory, but if the DOM nodes are about 10MB, for example, the page it starts to lose performance.
Both are stored in RAM. And both are stored in the Heap.
However, DOMs are more complicated than a simple image.
Here the DOM is represented as a tree, both abstractly, and in RAM. So, if the DOM gets too big, you lose performance drastically as it gets increasingly more expensive to get from root node to leaf node in this tree.
This is amplified dramatically by CSS and formatting rules. Since if a node at the top changes position, it could invalidate the entire tree with respect to CSS positioning. Additionally, if the node at the leaf changes position, it could still cause repositions to cascade up the tree.
In both directions, a large DOM tree can cause performance to come to a grinding halt.

React’s Virtual DOM

I know this might be a duplicate, but I really have some difficulties understanding this part of React’s reconciliation algorithm.
So Virtual DOM is in memory representation of the Real DOM. And whenever we call setState() React creates another copy of Virtual DOM and compares it with the previous one or it changes existing Virtual DOM and compares it with Real DOM?
Any changes are made or compared within Virtual DOM instances only.
When you do setState, React makes another copy of virtual DOM with the desired change and compares the old and the current virtual dom to only apply the change in the actual DOM in the browser
You can read more about Virtual DOM and its implemntation in the React docs
According to the Reconcilation link within the react docs
Reconciliation is the algorithm behind what is popularly understood as
the "virtual DOM." A high-level description goes something like this:
when you render a React application, a tree of nodes that describes
the app is generated and saved in memory. This tree is then flushed to
the rendering environment — for example, in the case of a browser
application, it's translated to a set of DOM operations. When the app
is updated (usually via setState), a new tree is generated. The new
tree is diffed with the previous tree to compute which operations are
needed to update the rendered app.

What is the performance cost of maintaining a live HTMLCollection?

A piece of my front-end JS code is depending on a live HTMLCollection of several thousand DOM nodes. Since it is live, it updates automatically as the DOM is updated.
Is this the same as re-running thedocument.getElementsByClassName call every single time I modify the DOM, or is there a performance optimization under the hood?
This blog post explains a little of the difference between static and live NodeLists, and mentions how live collections are implemented.
A live collection doesn't access the DOM until you access its elements. At that time it creates the actual collection and caches it. There's no overhead to future accesses if the DOM doesn't change.
Changing the DOM shouldn't cause an immediate update to any collections. Rather, it should just invalidate their caches. The next time you access one of the collections, it will be regenerated.
So if you create a live collection and access it infrequently compared to DOM modifications, there should be relatively little overhead. The worst case is if you loop over a live collection and modify the DOM during the loop -- each iteration will have to update the collection.
It's possible that there may be additional optimizations that could mitigate this. For some types of live collections, the JavaScript engine may be able to tell whether a particular DOM modification could affect it; if not, it doesn't have to invalidate the collection. For instance, a collection created with document.getElementsByClassName() would not be affected by a modification that doesn't add or remove the specified class anywhere. However, if you do something like delete an element, it would have to check whether the class appeared anywhere in the subtree headed by that element, so it's not obvious that this would really be better than just invalidating the caches.

Memory allocation and DOM elements

While reading an MDN article about Memory Management (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management) I came upon the following question: Is it right to say that
var e = document.getElementById('div_id');
allocates a DOM element? I am using the same words with MDN article. In my opinion this is not right since the element-object with id="div_id" is already created in memory as part of the DOM tree. So var e, just references it and does not allocate new memory. Am I right or not?
Thank you
document.getElementById('div_id') will not allocate memory for the element, as it already exists in the document tree.
However, the article you have linked doesn't actually say that memory would be allocated. So I don't see anything wrong with the article.
The only memory that gets allocated is for the variable e of the expression var e = document.getElementById('div_id');. This allocation happens in the stack. A new reference to the element is assigned to e, which consumes memory (even though it's a very small amount). No new memory allocation happens in the heap.
Yes, document.createElement('div/any tag'); will create a new node and hence it has to allocate memory for it.
I guess, the memory management in the document is talking about particular case as explained below. Suppose you create a DOM element
var myDom = document.createElement('dom'); //or consider array of dom objects
//attach dom objects to document using appendChild/insertBefore apis
//on some **event** you remove dom nodes from the document using removeChild api
But at last, if you forget that the myDom/array object you used to store DOM nodes is not freed up, the DOM objects will still exists in the memory, even though they are not attached to the docuemnt.
So, if you think the DOM is not used any more, assign myDom = null, this will make GC to free the space.
Doc : Release when the memory is not needed anymore
Most of memory management issues come at this phase. The hardest task
here is to find when "the allocated memory is not needed any longer".
It often requires for the developer to determine where in the program
such piece of memory is not needed anymore and free it.

Why is React's concept of Virtual DOM said to be more performant than dirty model checking?

I saw a React dev talk at (Pete Hunt: React: Rethinking best practices -- JSConf EU 2013) and the speaker mentioned that dirty-checking of the model can be slow. But isn't calculating the diff between virtual DOMs actually even less performant since the virtual DOM, in most of the cases, should be bigger than model?
I really like the potential power of the Virtual DOM (especially server-side rendering) but I would like to know all the pros and cons.
I'm the primary author of a virtual-dom module, so I might be able to answer your questions. There are in fact 2 problems that need to be solved here
When do I re-render? Answer: When I observe that the data is dirty.
How do I re-render efficiently? Answer: Using a virtual DOM to generate a real DOM patch
In React, each of your components have a state. This state is like an observable you might find in knockout or other MVVM style libraries. Essentially, React knows when to re-render the scene because it is able to observe when this data changes. Dirty checking is slower than observables because you must poll the data at a regular interval and check all of the values in the data structure recursively. By comparison, setting a value on the state will signal to a listener that some state has changed, so React can simply listen for change events on the state and queue up re-rendering.
The virtual DOM is used for efficient re-rendering of the DOM. This isn't really related to dirty checking your data. You could re-render using a virtual DOM with or without dirty checking. You're right in that there is some overhead in computing the diff between two virtual trees, but the virtual DOM diff is about understanding what needs updating in the DOM and not whether or not your data has changed. In fact, the diff algorithm is a dirty checker itself but it is used to see if the DOM is dirty instead.
We aim to re-render the virtual tree only when the state changes. So using an observable to check if the state has changed is an efficient way to prevent unnecessary re-renders, which would cause lots of unnecessary tree diffs. If nothing has changed, we do nothing.
A virtual DOM is nice because it lets us write our code as if we were re-rendering the entire scene. Behind the scenes we want to compute a patch operation that updates the DOM to look how we expect. So while the virtual DOM diff/patch algorithm is probably not the optimal solution, it gives us a very nice way to express our applications. We just declare exactly what we want and React/virtual-dom will work out how to make your scene look like this. We don't have to do manual DOM manipulation or get confused about previous DOM state. We don't have to re-render the entire scene either, which could be much less efficient than patching it.
I recently read a detailed article about React's diff algorithm here: http://calendar.perfplanet.com/2013/diff/. From what I understand, what makes React fast is:
Batched DOM read/write operations.
Efficient update of sub-tree only.
Compared to dirty-check, the key differences IMO are:
Model dirty-checking: React component is explicitly set as dirty whenever setState is called, so there's no comparison (of the data) needed here. For dirty-checking, the comparison (of the models) always happen each digest loop.
DOM updating: DOM operations are very expensive because modifying the DOM will also apply and calculate CSS styles, layouts. The saved time from unnecessary DOM modification can be longer than the time spent diffing the virtual DOM.
The second point is even more important for non-trivial models such as one with huge amount of fields or large list. One field change of complex model will result in only the operations needed for DOM elements involving that field, instead of the whole view/template.
I really like the potential power of the Virtual DOM (especially
server-side rendering) but I would like to know all the pros and cons.
-- OP
React is not the only DOM manipulation library. I encourage you to understand the alternatives by reading this article from Auth0 that includes detailed explanation and benchmarks. I'll highlight here their pros and cons, as you asked:
React.js' Virtual DOM
PROS
Fast and efficient "diffing" algorithm
Multiple frontends (JSX, hyperscript)
Lightweight enough to run on mobile devices
Lots of traction and mindshare
Can be used without React (i.e. as an independent engine)
CONS
Full in-memory copy of the DOM (higher memory use)
No differentiation between static and dynamic elements
Ember.js' Glimmer
PROS
Fast and efficient diffing algorithm
Differentiation between static and dynamic elements
100% compatible with Ember's API (you get the benefits without major updates to your existing code)
Lightweight in-memory representation of the DOM
CONS
Meant to be used only in Ember
Only one frontend available
Incremental DOM
PROS
Reduced memory usage
Simple API
Easily integrates with many frontends and frameworks (meant as a template engine backend from the beginning)
CONS
Not as fast as other libraries (this is arguable, see the benchmarks below)
Less mindshare and community use
Here's a comment by React team member Sebastian Markbåge which sheds some light:
React does the diffing on the output (which is a known serializable format, DOM attributes). This means that the source data can be of any format. It can be immutable data structures and state inside of closures.
The Angular model doesn't preserve referential transparency and therefore is inherently mutable. You mutate the existing model to track changes. What if your data source is immutable data or a new data structure every time (such as a JSON response)?
Dirty checking and Object.observe does not work on closure scope state.
These two things are very limiting to functional patterns obviously.
Additionally, when your model complexity grows, it becomes increasingly expensive to do dirty tracking. However, if you only do diffing on the visual tree, like React, then it doesn't grow as much since the amount of data you're able to show on the screen at any given point is limited by UIs. Pete's link above covers more of the perf benefits.
https://news.ycombinator.com/item?id=6937668
In React, each of your components have a state. This state is like an observable you might find in knockout or other MVVM style libraries. Essentially, React knows when to re-render the scene because it is able to observe when this data changes. Dirty checking is slower than observables because you must poll the data at a regular interval and check all of the values in the data structure recursively. By comparison, setting a value on the state will signal to a listener that some state has changed, so React can simply listen for change events on the state and queue up re-rendering.The virtual DOM is used for efficient re-rendering of the DOM. This isn't really related to dirty checking your data. You could re-render using a virtual DOM with or without dirty checking. You're right in that there is some overhead in computing the diff between two virtual trees, but the virtual DOM diff is about understanding what needs updating in the DOM and not whether or not your data has changed. In fact, the diff algorithm is a dirty checker itself but it is used to see if the DOM is dirty instead.
We aim to re-render the virtual tree only when the state changes. So using an observable to check if the state has changed is an efficient way to prevent unnecessary re-renders, which would cause lots of unnecessary tree diffs. If nothing has changed, we do nothing.
Virtual Dom is not invented by react. It is part of HTML dom.
It is lightweight and detached from the browser-specific implementation details.
We can think virtual DOM as React’s local and simplified copy of the HTML DOM. It allows React to do its computations within this abstract world and skip the “real” DOM operations, often slow and browser-specific. Actually there is no big differenc between DOM and VIRTUAL DOM.
Below are the points why Virtual Dom is used (source Virtual DOM in ReactJS):
When you do:
document.getElementById('elementId').innerHTML = "New Value" Following thing happens:
Browser needs to parse the HTML
It removes the child element of elementId
Updates the DOM value with new value
Re-calculate the css for the parent and child
Update the layout i.e. each elements exact co-ordinates on the screen
Traverse the render tree and paint it on the browser display
Recalculating the CSS and changed layouts uses complex algorithm and
they effect the performance.
As well as updating the DOM properties ie. values. It follows a algorithm.
Now, suppose if you update DOM 10 times directly, then all the above steps will run one by one and updating DOM algorithms will take time to updates DOM values.
This, is why Real DOM is slower than virtual DOM.

Categories

Resources