←back to thread

69 points jdkoeck | 4 comments | | HN request time: 0.002s | source
Show context
MrJohz ◴[] No.44438306[source]
My biggest criticism of this design is that the author doesn't seem to have explored how Svelte, Vue Vapor or SolidJS work at all. The design seems largely based on the idea that rendering the template is a cheap operation, and that it can be done repeatedly whenever values change. So it's fine to have something like html`<div>${arr.map(el => html`...${el}...`)}</div>`, because each time the array changes, rendering every item in the list is a cheap operation. And it's typically cheap because it's rendering to a VDOM-like structure, and the more expensive diffing happens later.

But modern signal-based frameworks tend to work on the basis that doing these of rendering for each change is unnecessary, and so you should only update the relevant part of the DOM. This means rendering as seldom as often, in particular when handling conditionals and lists. This is why both SolidJS and Vue Vapor both have helpers for rendering lists and conditional elements, because if you just use `.map` and the ternary operator, things aren't going to work as you'd expect. Svelte has its own syntax but in principle works very similarly.

This proposal feels like it's very oriented around the React/Lit VDOM mechanism, with a handful of Preact-like concessions to signals where they are relatively easy to retrofit into a VDOM-like system. The problem is that these sorts of frameworks are heavyweight, slow, cumbersome things, because they're doing so much extra work. Codifying that sort of inefficiency directly into the browser seems like a terrible idea.

My second biggest criticism of this proposal is that I'm really struggling to see the benefit of it, i.e. who it's for. It can't be for framework compatibility, because it's not addressing any of the issues that actually make frameworks incompatible with each other (different state/context mechanisms, different lifecycles, etc). It can't be to codify common rendering idioms and optimise them by letting the browser implement them natively, because, as discussed, the proposal doesn't leave a lot of room for well-optimised frameworks. So I guess the idea is to ensure that the browser has a built-in web framework to make it easier for people to build complex web applications without needing to import lots of dependencies.

But if you're building a complex web application, the sort that needs specialised rendering like this, the overhead of a web framework is probably pretty minimal anyway. And if you're building simpler sites with minor interactivity, this sort of rendering system is complete overkill. You'd be better if writing a wrapper around document.createElement and going from there.

replies(2): >>44438815 #>>44438861 #
jfagnani ◴[] No.44438861[source]
I've definitely explored how those frameworks work, and I've written several signals integrations for Lit.

My claim, having done that, is that template re-rendering and fine-grained reactivity are entirely compatible, and neither takes away from the other.

Template re-rendering is incredibly cheap, and not at all like React/vdom. It does a few simple checks: 1) that the new template is the same as the last, 2) it runs through the linear list of values and compares them to the last, writing them if they changed. This isn't like VDOM which has to traverse two fine-grained vdom trees comparing for differences. Many huge web applications like Photoshop, Reddit, and parts of YouTube use template re-rendering.

And signals work great with this. If your template is "signal pure" then it never needs to re-render. If it's partially signals and partially non-signal data, then it only needs to re-render when non-signal data changes.

Signals are great, but signal-only systems require that all data be wrapped in them. And I have seen large apps have problems with the memory overhead of the automatic dependency tracking and change detection at each composed signal in the graph. Memory pressure and GC could be problematic for the TC39 signals proposal (though hopefully not).

To answer your next point about who this is for: lots of different audiences.

First is plain web devs. I've seen in multiple large dev orgs moves to standardize all DOM creation outside of frameworks on lit-html or something similar, mainly out of security concerns. But templated DOM creation is so common, that it's really a big whole in the web platform that it's not built in. The only reason it's not is that platform maintainers are afraid of stepping on the toes of frameworks. I don't think that's a good reason.

Second is frameworks. Whether or not the exact set of current frameworks migrate to this, a framework created for a platform with templating built-in would have a high probably of just using it instead of rolling their own. You can easily imagine a React-alike built on top of this API, as I've seen people do with lit-html. That reduces code size and increases perform for libraries and users.

Third is web components authors. Many reach for something like Lit main for the templating. I don't think they should have to, even as the maintainer of Lit. Vanilla web components + native templating takes care of a large amount of component concerns for those developers.

Fourth is the platform itself. Part of my reason for working on this proposal now as opposed to my usual "I'll get to that one day" tasks is because I've seen so many people ask for an HTML-based templating solution, ie a better `<template>`. I support that, but I don't think we can easily get there all at once. This is an attempt to build the story and capabilities for the subset of features that an JS API needs first so that the infrastructure can be used for HTML templates. If the JS API gets in, then the HTML API can reuse it, adding the expressions, scopes, control flow, etc., that HTML needs and JS doesn't.

replies(1): >>44439262 #
1. MrJohz ◴[] No.44439262[source]
> Many huge web applications like Photoshop, Reddit, and parts of YouTube use template re-rendering.

Those examples do not seem like ringing endorsements of this technique!

For basic functionality - when the template stays the same - I can see how this would be reasonably efficient. But inevitably you're going to end to rendering conditionals or loops, and that surely causes problems. For example, consider an array of signals. We use `.map` in a template to loop over the elements of the array and render something for each element. Now we append a new element to the array. How does this system ensure that only this new element gets rendered, without any of the other entries bring rerendered as well.

> First is plain web devs.

The security concerns are legitimate, but a full templating system is an overkill of a solution. Why not focus on those specific needs? The easiest system would be a simpler way to create and update DOM nodes dynamically, that bakes security into the system from the start - something like hyperscript that allows attributes and properties to be set, but handles escaping correctly.

> Second is frameworks.

Do you have any evidence that frameworks will want to standardise onto this, or that it will be in any way beneficial (beyond the vague feeling that there's more standardisation happening so things must be better)? There are such significant differences between frameworks even in terms of simple things like when a render or DOM update happens that it's difficult to see where frameworks would get value from a tool like this. Creating DOM nodes from scratch isn't that difficult!

> Third is web components authors.

Extending this to application devs in general, because the point about web components seems original to everything else here: is this not just picking an arbitrary framework and embedding it into the browser? That feels like if Python decided that Flask was the best web framework and decided to add it to the standard library: very convenient for those using Flask, but from then on a continual burden for anyone maintaining the language. And much like how Flask has become increasingly obsolete in Python's new asyncio world, what stops this templating mechanism from going from useful to just a new maintenance burden for browsers? And keep in mind how much has changed for frontend frameworks just in the last five years or so. Is right now really the right moment to standardise?

> Fourth is the platform itself.

It would certainly be nice if the platform had some sort of templating mechanism. There's a lot of other stuff that would be great as well. But continually adding features makes existing browsers harder to maintain, and new browsers harder to develop. There has to be some measure of balance here between the myriad of "nice to haves" and the constant increase in complexity and surface area.

Especially here, this feels like standardisation in the XKCD sense: it's not great that there's a bunch of competing frameworks, but adding a new one to the mix won't solve that problem. What's particularly irritating here is that you reference an example where standardisation has been done much better: the signals proposal was started after a bunch of libraries and tools had already demonstrated the value of signals, and formed some clear patterns that were near-universal. There was a specific need for interoperability (because otherwise different signals implementations cannot interact with each other), and the developers of the various signal libraries were involved pretty much from the start.

This feels very different from that process! Here, the differences between different favourite is far, far greater, interoperability is much less important, and it doesn't look like there's been much input at all from the developers of those other frameworks.

replies(1): >>44441002 #
2. jdkoeck ◴[] No.44441002[source]
Just a quick answer to a point that jumped at me: for an array of signals, you wouldn’t need to map them, you’d use a specialised directive that directly takes an array of signals and binds them to the DOM, the same way lit uses the repeat() directive to optimise the rendering of arrays.

https://lit.dev/docs/templates/lists/#the-repeat-directive

replies(1): >>44442058 #
3. MrJohz ◴[] No.44442058[source]
Hmm, I really don't like the idea that you would have these kinds of directives as specialised tools, rather than having a single standard approach. From experience, it's often hard to explain the differences between these sorts of different directives, especially if someone is coming from a React/VDOM perspective where everything Just Works™. This feels like a very significant impedance mismatch that will cause problems in practical usage.
replies(1): >>44451976 #
4. jdkoeck ◴[] No.44451976{3}[source]
On the contrary, I think this a very practical escape hatch that will let frameworks insert optimisations where they need to.

I don’t know if React really Just Works these days, the VDOM has real overhead and developing with React feels like playing whack-a-mole with rerenders these days.