(thanks to whoever bothered to do this writeup).
https://github.com/gactjs/gact/blob/master/docs/long-live-th...
EDIT: if anyone has proof this is not true, I'd love to hear their counterargument.
(thanks to whoever bothered to do this writeup).
https://github.com/gactjs/gact/blob/master/docs/long-live-th...
EDIT: if anyone has proof this is not true, I'd love to hear their counterargument.
DOM nodes can actually be recycled relatively easily. Cache the nodes by type then by class. Most recycled nodes would be a 100% match based on those two alone. If type and class match, then you have a super-high probability of dealing with old nodes for the same object, so few modifications are required. Most nodes without classes tend to have no attributes changed (<div>, <p>, etc) so they will match as well. Store those nodes with their vdom attached and you will have a record of what has been modified so patching is fast.
This optimization exists in some vdom implementations and would make the case in question much faster. There also seems to be an implication that the diffing algorithm will bloat. If you look at React, the diffing algorithm is a very small part of the codebase.
This is hardly just an academic optimization though. It is the key to reducing overhead on long lists. With long lists of complex objects, you cannot rely on patching text values because there will undoubtedly be actual DOM differences. Rather than dooming the entire list to poor performance, you can recycle those nodes and retain most of the performance of a flyweight scroller where nodes are all identical.
https://developers.google.com/web/updates/2016/07/infinite-s...
In that very simplistic example, there are only 4 nodes to each list, so creating and destroying them doesn't matter. I have a scroller in a business app where each item has a few hundred DOM nodes. Create and destroy them constantly and you'll definitely notice on a desktop and performance will crawl on a mobile device.
Instead, you want to save those DOM nodes in a cache and re-use them. In order to do this though, you must know what parts are default and what parts have been modified by their previous user. A vdom does this automatically, but the cost for Svelte to calculate which of the hundreds of properties have changed is too big, so they just throw it away and make another.
An even better optimization would be where each list item has the same node structure and only text or images change. I believe Svelte can handle this case. Unfortunately a lot of lists are slightly irregular in real-world applications. I work with these kinds of lists a lot and a vdom keeps it smoother than all the other libraries we've looked at.
How would Svelte know what things had been changed when looking at a node saved in a cache?
If it has to check every property, the cost to check will exceed the cost to create new. If it saves a list of changes, it's essentially created a vdom anyway.
For example, even changing a single value in a big list requires the whole VDOM to be recreated, but should be very efficient in Svelte as it can directly modify the specific DOM node. On the other hand, as pointed out in the article you linked, if changing a value affects a large part of the DOM, but does not actually change that much, then value-comparing frameworks (e.g. Svelte) probably do a lot of unnecessary work compared to VDOM-based approaches (intuitively I would think that this case does not occur that often).
Changing branches in a component is extremely common in code I write (very large business application with lots of rules).
Another important optimization is caching and re-using DOM nodes. With a vdom, you know exactly which properties and attributes differ from the default node. To reuse a node you need only update these properties to their new values or restore their original values. Without that tracking, it would be computationally cheaper to just create a new node.
One important example of this is our use of flyweight scroller patterns in lists. The content of the sub-tree changes, but most of the sub-components stay the same, so a vdom could keep most of the dom nodes around.
Here is the repl of the code you posted.
https://svelte.dev/repl/1a70f2f38af94ed7ac8bd032feea52f9?ver...
A Svelte component is mutable & manages the related DOM elements which are also mutable. In the conditional, the tree is re-rendered.
Would React's diff algorithm be able to recycle the `<p>surgical</p>` DOM Node? How much more performant would detaching & reattaching `<p>surgical</p>` be than recreating `<p>surgical</p>`?
Assuming the `<p>surgical</p>` can be recycled, the use case having the largest effect is a large inner tree being wrapped/unwrapped; where the inner tree would simply be moved instead of recreated.
In Svelte, this can be optimized by using a subcomponent, as seen in the repl example. You can examine the compiled js.
I may be wrong, but I believe hyperapp recycles both the physical DOM node and the attached vdom node together (IIRC, they mark reused vdom nodes as "recycled" instead of directly comparing objects so they don't have to construct as many new vdom objects).
Preact kinda cheats here because they diff against the DOM directly.
There’s more discussion here:https://mobile.twitter.com/Shub7241/status/11570049077753241....