The idea is to have much faster rendering (a compiler optimizes virtual DOM beforehand) while ensuring the same developer experience React provides.
This is very, VERY early stage, so be prepared for weird bugs / plugin incompatibility / etc. If you have any suggestions, I'd be more than happy if you replied in a comment with it!
You can spin up the demo here >> https://stackblitz.com/github/aidenybai/million-react-compat
Rather than creating and diffing a fine-grained tree of elements every render, it's very easy to use the syntactic structure of a template to see exactly what parts can and cannot change. To get stable and minimal DOM updates you just compare the template identity to the previously rendered template - if they match you update the dynamic expressions, if they don't you clear and render the new template.
This is what we did with lit-html and it's quite a bit faster (and smaller) than React and doesn't require a compiler because it uses standard JS tagged template literals. https://lit.dev/docs/libraries/standalone-templates/
It's a very simple approach and very, very hard to beat in the fast/small/simple/buildless tradeoff space. I hope one day that the DOM can include standard updatable DOM with a technique like this on top of the template instantiation proposal from Apple. It's such a common need that it should be built in.
He's arguing about speed and saying why the approach of lit-html will always be faster than virtual dom.
I think it's fair since OP is trying to get a faster vdom to also expect discussions about different approaches and I'm glad the previous user gave his two cents.
There was no put-down. There was a very informative and insightful post explaining that a) unlike the original claim, the project does not use a virtual DOM, b) the technique used is indeed very performant and hard to beat, c) other projects also use it.
You need to go way outside of your way to pretend to feel any sort of outrage over this.
Author of the ivi library here. Completely agree with an idea that such approach could lead to a better performance, but there is a huge difference between an idea and actual implementation. Also, I just don't get it why a lot developers that work in this problem space still think like "virtual DOM" API and tagged template APIs are mutually exclusive, I've actually have an experimental implementation that supports both APIs and it is not so easy to beat efficient full diff vdom algo. Tagged template APIs are useful when we are working with mostly static HTML chunks, but when it comes to building a set of reusable components (not expensive web components), pretty much everything inside this components becomes dynamic and we are back to diffing everything.
This isn't to say virtual DOM isn't fast Experimental libraries that use virtual DOM's like blockdom and ivi (see https://krausest.github.io/js-framework-benchmark/2022/table...) are very, very fast.
At the end of the day, the way libraries render UI is a set of tradeoffs. No one method is objectively better. While lit works great for a lot of web developers, so do virtual DOM based libraries
Totally agree on native DOM diffing, I'll check out Apple's proposal :)
There is probably a good reason popular frameworks insist on using it though.
Every component in the DOM has an ID and a hash. Client-side events that mutate state automatically modify this hash as well. The server keeps a dictionay of active components per client. At view state sync time, components are first created and removed on an identity basis. Then, all existing components have their hashes compared for equality. Depending on the type, various patch commands will be submitted to the client to realign the element to expected state.
In most cases, each component involves multiple DOM elements. By scanning for the component root elements via attributes, we can avoid having to walk through the entire literal DOM each time. This may have profound consequences for table views and other enumerables.
I have zero clue if this is the fastest/best, but its simple as hell and looks starts to look like butter as you polish each standardized component.
Only real downside is the latency constraint, but this is something we can pretty easily overcome for our users with some well-placed frontend VMs. Definitely wouldn't do something like this for Netflix scale, unless someone told me the economics of 1 websocket per client works now... On average, how many DAUs per VM does Netflix run these days?
I feel like there is at least one Haskell library out there that automates this "no virtual DOM" problem. In Haskell it is not uncommon to create data structures on the fly, only to deconstruct them immediately again. If done correctly the compiler can remove the immediate structure completely, leaving a (recursive) algorithm.
An example of this would be sorting via binary trees. If done correctly, the intermediate tree is never (completely) present in ram.
https://github.com/WICG/webcomponents/blob/gh-pages/proposal...
You can learn more of the history here:
https://www.w3.org/2020/10/TPAC/parts_and_template_instantia...
https://github.com/WICG/webcomponents/blob/gh-pages/proposal...
Internally it compiles down to template literals, so the same advantages apply.
The typescript support for lit is lagging to say the least. It is surprising that there is still no good official support for type-checking of templates. There are a few community projects though but they are not as reliable and the DOM/Web Component API doesn't make it easy to make fully type-safe APIs.
Solid being able to lean in the JSX support in the TS compiler and not tying itself to custom elements api is able to offer a much better DX here.
Considering the pretty docs, I'm guessing you're trying to get people to use this. It would be useful to have the value proposition front-and-center (e.g. in your README).
If someone is in the React mainstream, they use React. If they like the devex of React but want something simpler/more streamlined, they use Preact. I'd appreciate a "This is why you might choose this library instead of Preact. This is why this is a new library instead of a patch to Preact. This is an honest assessment of when React/Preact is a better choice than Million." section.
There are often tradeoffs in library development. Being honest about the ones you chose helps other developers trust you.
In retrospect, I think what really confused me was that React components return HTML, which is a weird semantic I can't intuit, after a few attempts. Svelte lets you declare everything separately, while being more succinct and readable (IMO at least).
I feel like the main pain point with React is that routing, bundling, SSR, state management, etc. have to be painfully stapled together, and this is what frameworks like Next.js solve for.
And is it just a monetary cost?
Yes, if energy use is your primary concern there are easier ways to reduce it. But in the above context it seems clear that you should take your gains where you can get them.
What's your opinion on Hook-style APIs?
Hook style API allows us to write the same functionality with less keystrokes. But I found that I interpret how it works object-orientedly. It feels wierd to write them as functions instead of classes.
If there are multiple appearances of the same component, they belong to different "instances". Components get updated by modifying their state, or in other words, their "instance variables".
Is the router you are using solid-app-router [1] ? Have been working with it for last few months and it has been generally stable (my usecases are not particularly complex though).
The docs for the solidjs core has also massively improved recently.
const [value, setValue] = useState(0);
should be: const [value, setValue] = useState(init);
or the parameter init could be removed from the component.Other than that, thank you so much for all the awesome feedback, it's really appreciated :)