News for hackers. Stuff that matters.
Re:How I built a fast JavaScript framework by amelius on Wednesday March 07, 2018 @11:42AM (#16537581)
The problem with not using a virtual DOM is that you can't merge in changes to stateful DOM elements. For example, an INPUT field has state (its value, plus its scroll position). If you regenerate the INPUT field from scratch, you risk losing the state. In contrast, if you use a virtual DOM, the vdom mechanism can merge in any changes for you (the INPUT field will stay the object!)

Of course, you can recreate DOM elements with their complete state, but if you'd try to do that with e.g. a VIDEO element, then you risk flicker and reloading of the actual video.

Re:How I built a fast JavaScript framework by lhorie on Wednesday March 07, 2018 @11:56AM (#16537707)
This isn't quite correct. Modern rendering libraries aren't going to recreate an input from scratch unless they absolutely have to, vdom or not.

What's tricky about reconciling app state changes and dom state is dealing with things like cursor position if e.g. the input value change comes from a socket and the user had the input focused and the cursor in the middle of the text. But this has nothing to do with vdom

Re:How I built a fast JavaScript framework by amelius on Wednesday March 07, 2018 @02:30PM (#16539091)
To prove you wrong, consider how DOM elements are created (remember in Surplus there are no virtual elements). Ignoring all dependency tracking, the code to show some text has to be (eventually) of the form

    x = document.createTextNode(v);
Now, consider the dependency v changes. The only option is to run the code above again, in its entirety. And thus, the DOM node corresponding to the text is new.

Of course, a smart library will ensure that the amount of nodes that has to be visited is at a minimum. But that doesn't mean DOM nodes don't get rebuilt from scratch.

Re:How I built a fast JavaScript framework by lhorie on Wednesday March 07, 2018 @03:47PM (#16539726)
> The only option is to run the code above again, in its entirety

Not at all. The reactive pattern typically boils down to something like this:

    el = document.createTextNode(initialValue);
    parent.appendChild(el);
    reactiveValue.onchange(v => {
      el.nodeValue = v;
    })
Ironically, in this specific example, vdom libs typically do this when possible:

    parent.textContent = v
which does in fact replace the underlying text node, but they do so for the sake of performance
Re:How I built a fast JavaScript framework by amelius on Wednesday March 07, 2018 @05:37PM (#16540635)
Yes, you can code like that, but ultimately that block will be contained inside a closure that will get triggered by some change. Of course, unless you are very careful.
Re:How I built a fast JavaScript framework by lhorie on Wednesday March 07, 2018 @05:58PM (#16540777)
The element creation part will be triggered if a creation is required. It won't be triggered by a prop update, for instance.

In the following example, I change the button id on click. It's still the same button element after the change:

https://jsfiddle.net/dwn36aw4/8/

Re:How I built a fast JavaScript framework by amelius on Wednesday March 07, 2018 @06:28PM (#16540966)
But it's very difficult to prevent unnecessary dependencies from triggering in all cases. Consider a map (dict) with some values. Some outer code depends on the map. This code builds some DOM elements and sets values based on the values in the map. Now, if the map changes, all the elements will be recreated, even if effectively some irrelevant part of the map changed. Of course you can prevent this from happening by doing smart diffing on the map, but now you've effectively moved the problem from dom-diffing to map-diffing.
Re:How I built a fast JavaScript framework by lhorie on Wednesday March 07, 2018 @07:57PM (#16541373)
I wrote about that (and the drawbacks and alternative takes) here: https://news.ycombinator.com/item?id=16540223 but yes, in a nutshell, "move the problem from dom-diffing to map-diffing" is basically what a reactive system is supposed to be taking care of.

You're absolutely right that reactive systems are not trivial to implement (let alone implement well), but inefficient DOM recreation under these systems is a symptom of poor granularity in the reactive layer (which may be a problem with the reactivity library just as well as it could be poor usage of its API), rather than a limitation of the rendering library itself.

Re:How I built a fast JavaScript framework by amelius on Thursday March 08, 2018 @05:35AM (#16543543)
Ok, that makes sense.

I'm also worried about debugging accidental dependency triggers. Imagine that suddenly the scroll-state of some div is reset; how do you determine which dependency caused the DOM element to be recreated? With a vdom you avoid the whole problem.

Re:How I built a fast JavaScript framework by lhorie on Thursday March 08, 2018 @11:24AM (#16545344)
> how do you determine which dependency caused the DOM element to be recreated

Normally, I would toss in a throw and look at the stack trace. But yes, the stack trace gets noisy as hell.

Re:How I built a fast JavaScript framework by merb on Wednesday March 07, 2018 @03:26PM (#16539523)
what you discribe is basically what https://github.com/google/incremental-dom is all about and in certain cases it probably is as fast as vdom and also less memory heavy.
Re:How I built a fast JavaScript framework by naasking on Wednesday March 07, 2018 @11:45AM (#16537611)
I don't see why this would be any more difficult without a vdom. For the textarea, either way you're merging two text blobs, and if the vdom can maintain scroll position while doing this, then so can the non-vdom using the same mechanism.
Re:How I built a fast JavaScript framework by amelius on Wednesday March 07, 2018 @12:10PM (#16537825)
Let me try to explain. Let's say you have a textarea element which has DOM-state (value, scroll-position). And let's say you change the value through your render-framework. With the vdom approach, only the value component of the DOM-state is modified. With the non-vdom approach, you're creating a new textarea element, and set its value. Its scroll-position is lost, unless you keep track of it.

Now with VIDEO elements, things are more problematic. If you recreate parent-nodes of a VIDEO element, the video will stop playing, or will flicker, or jump back to the beginning.

Re:How I built a fast JavaScript framework by naasking on Wednesday March 07, 2018 @12:13PM (#16537844)
> With the non-vdom approach, you're creating a new textarea element, and set its value.

This isn't necessarily true. In fact, it's not true of Surplus and Radi.js, which is partly why they're much faster than every vdom framework out there.

Re:How I built a fast JavaScript framework by amelius on Wednesday March 07, 2018 @12:17PM (#16537879)
They're faster because they are not computing DOM (or vdom) nodes when that's not needed.

But they're creating new DOM nodes when values-on-which-the-code-depends change.