Hacker News new | ask | show | jobs
by recursive 679 days ago
> You want to return a description of the DOM, rather than the real DOM, because you want to be able to reevaluate your templates repeatedly with new state, and efficiently update the DOM where that template is rendered to.

Depends who "you" are. I prefer to have my DOM nodes updated in place without all the reconciliation machinery. (no implication about what you want)

2 comments

If you work on a team of suitable size I would hesitate to not leverage a VDom. I trust myself to not trigger dumb reflows, but the way I see a lot of people using React this could be a perf nightmare.
I think that hits the real problem: it’s staffing and culture, not the tool. The 90th percentile site using a vDOM is also a perf nightmare, especially for anyone who doesn’t have a recent Apple device on a fast network, and that often has big impacts on usability and accessibility as well (dynamic loading sucks on screen readers unless you put way more time into it that most people do).

I was painfully reminded of that while visiting Europe last month on a data plan which was clearly deprioritized on partner networks - the old sites with .php in the URLs loaded in a few seconds and worked perfectly, but every time something failed to load in less than 5 minutes or partially loaded but didn’t work a quick trip over to webpagetest.org showed a lot of NextJS, React, et al. scripts trickling in because clearly a form with half a dozen fields needs 25MB of JavaScript.

The root cause is obvious: you get what you measure. If businesses prioritize Jira tickets closed per day, they’re going to get this soup of things promising to be easy to use for high developer velocity and they’re never going to get around to the optimizing it. If they’re trying to be able to hire as cheaply as possible, they’re going to look for the current tool boot camps are pushing and hire based on that, not looking for deeper knowledge of web standards or experience which costs more and shrink the candidate pool. If they’re looking for a safe choice, Facebook’s marketing means all of the big consulting companies will push React and few people will pause long enough to ask whether they’re building the same kind of apps it was designed to build (long session times, tons of local state being mutated, etc.) or whether they’re willing to invest the time needed to get it to perform reliably and well.

There are more and more frameworks that avoid the VDOM but still resolve this fine. As long as DOM mutation is handled by the framework (and not done ad-hoc), and as long as the framework has a mechanism for deferring those mutations until after all reads, then there shouldn't be a problem. This is the approach taken by SolidJS, Svelte, and even the new rendering model for VueJS.

In all these frameworks, mutations happen inside effects, and effects are scheduled such that they all happen at the end of the tick, avoiding reflows and thrashing.

You don't need diffing or reconciliation to turn a description of DOM into DOM. Lit works without a VDOM.

If all JSX does is return a DocumentFragment that you then need to imperatively add event listeners to and imperatively update, how is it much better than innerHTML?

innerHTML loses all local state, such as which elements have focus or where the cursor is in a text field. Back when React first came out and people were getting used to the idea of VDOM diffing, they had demos front and center about how by using those diffs to only change what needed to change, such local state wouldn't be lost.

This in theory could do something to copy that local state over, or diff the two DOMs directly without a VDOM (though from the sound of it, it probably doesn't).

I think the answer to that is probably "as good as soy, but with modern ergonomics". E4X was basically this and I think it's a much nicer way to build DOM trees than strings since you can't create invalid markup or concat partial tags. It also lets you reuse subtrees naturally where innerHTML makes that impossible.
You can have JSX that produces DOM nodes or "light-weight element descriptions".

You can have imperative event listeners and updates.

These are two independent dimensions. I made UI framework called mutraction that produces real DOM elements from JSX expressions. It also updates any contents or attributes of those DOM nodes based on their dependencies without requiring imperative DOM interaction from application code.

https://github.com/tomtheisen/mutraction

Here's a click counter. `track()`, as you might guess creates a proxy so that reads and writes can be converted into dependencies.

    const model = track({ clicks: 0});
    const app = (
        <button onclick={() => ++model.clicks }>
            { model.clicks } clicks
        </button>
    );

    document.body.append(app);
1) Type safety for element props.

2) Autocomplete for element props.

3) IDE support such as refactors and jump to definition/jump to usages.

4) Proper syntax highlighting out of the box instead of the editor just saying "there's a string here".

5) A uniform pattern for defining custom components that work the same as primitives, rather than defining custom components as helper functions returning string fragments or something like that.

And so on. JSX has a lot going for it regardless of the semantics chosen. It's just a syntax that is very convenient for lots of kinds of tooling, and it's completely unopinated about the semantic context in which it is used.

These are definitely helpful, but what you are describing are all language tool features rather than features of JSX itself. 5 would be the exception, but that is just user preference of what kind of syntax one likes to write components with.
Well, yes. But OP was asking about what makes this better than `innerHTML`, and the obvious answer is that support for HTML programming embedded in JavaScript strings is generally bad while support for JSX is very good across all editors.