top | item 34738792

Cample.js: Reactivity without virtual DOM

50 points| Cample | 3 years ago |github.com | reply

92 comments

order
[+] ribit|3 years ago|reply
There are at least two reasonably popular frameworks that offer reactivity without virtual DOM: Svelte and Solid. And both of them are way more ergonomic than what is presented here.

I believe VDOM-based approaches have one decisive advantage — the VDOM structure can be created by any means convenient to the programmer. To me at least, this offers more flexibility and modularity when organising code: you can create as many functions as you need to structure and reuse VDOM construction. This is something I run into with Svelte, which forces me to make a new component for every bit of code I try to isolate. Solid is a bit better — and I really like their idea of "vanishing components" — but you have to follow it's fairly strict rules (e.g. no props destructuring) or things will get weird.

[+] fabiospampinato|3 years ago|reply
By and large having no VDOM frees you from having to structure things in an unergonomic way, for performance or otherwise, whatever limitations Svelte and Solid have in this regard are self-inflicted. For example my framework allows you to destructure props just fine, still no VDOM (https://github.com/vobyjs/voby).
[+] spankalee|3 years ago|reply
You can do the same with any system that treats templates as expressions that return a value (the big innovation of React, IMO), it doesn't require vdom.

In Lit, we do this with tagged standard template literal expressions that return what we call a TemplateResult. You can compute, store, abstract over those however you want - they're just JS values. This indeed gives programers a ton of expressive power.

[+] mrozbarry|3 years ago|reply
People like to hate on the VDOM, but here's some food for thought:

- VDOM is data-driven without side-effects

- VDOM does not actually require JSX or build steps

- VDOM decouples you from the real dom, which has allowed things like react-native to "just work" the way react web works.

- VDOM means you can make test assertions without having to load up a "browser-like" environment

- JSON is a pretty easy to reason-about data structure, which makes debugging fairly easy

I'm not saying the virtual dom is the best answer, but I guess my point is that it's not really an issue of speed any more. If I recall my internet history, React came at a time when browser DOM standardization was still pretty wonky, so the virtual dom did provide a boost in manipulating the data that would translate to DOM mutations. Now that we're basically all running Chrome or Firefox under the hood (give or take webkit safari), I'm not sure that's the main drive any more, but the other benefits still stand, and that's why things like react are still using the virtual dom.

Anyway, cool library. I'm curious if it provides something that is actually different from other libraries I've used, in terms of interface or flow, and I might find some time to check it out soon. Good job!

[+] kristiandupont|3 years ago|reply
First off, I am always happy to see people trying out new things because it creates innovation. Congratulations on launching!

That said, the big feature here seems to be what the headline says: no virtual DOM. As a user of frameworks, I don't care much about implementation details unless they result in benefits like performance improvements. Does this perform better than React and/or Vue? Or is there some other benefit to it?

[+] fabiospampinato|3 years ago|reply
Things like Solid (https://www.solidjs.com/) also have no virtual DOM, and the improvements are in higher ceiling for performance, lower memory usage, simpler DX (components are not re-executed, there aren't any dependency arrays anywhere), easy high performance (no useRef this and useRef that to make things fast, no useCallback, no React.memo, these things are just obsolete).
[+] larsonnn|3 years ago|reply
I wouldn’t call it a new thing. We began without virtual DOM and then Facebook sold us the vDOM as the ultimate way to go. Which svelte clearly shows, by removing the unnecessary layer for the vdom it’s much faster and is still reactive.
[+] ulizzle|3 years ago|reply
Yeah, it does have significant performance improvements, because diffing the Virtual Dom adds heavily to computation costs if you aren't being extra careful or as the application grows to real-world size, especially in mobile.

No VDom is always faster than having a VDom.

But I do agree with your point 100% that it should tell you right away about it on the README what that means, and the significance behind the claim.

[+] andy_ppp|3 years ago|reply
Yes was going to say exactly this, tell my updates are faster or the library is smaller but just saying we built it without virtual DOM doesn’t explain the trade offs in this approach.
[+] synergy20|3 years ago|reply
How is it different from svlete and solidjs? both are no-VDom approaches.
[+] a_c|3 years ago|reply
Can someone remind me why virtual DOM was/is desirable in the first place and why updating the DOM directly is desirable now?

If I understand correctly react elements are created in memory, and only upon "render" it is turned into the actual DOM. During render in react, it does the tree diffing and state management. Supposedly manipulating the actual DOM directly is "heavy" hence delay/pruning the virtual DOM tree first then rendering would be beneficial? Then why is it working with DOM directly is desirable? And am I right to assume that "without virtual DOM" means work with DOM directly? Someone in the comment mention that Svelte is without vDOM already. Is there some design document that I can refer to, like the reconciliation engine used in react https://github.com/acdlite/react-fiber-architecture

[+] gspencley|3 years ago|reply
I don't know why VirtualDOM is suddenly getting a bad rep. The reason you often want something like a VirtualDOM is so that you can "pre-process" your DOM updates in-memory so that the actual updates, which are computationally expensive for the browser, can be done more efficiently.

I suspect, but this is just my personal conjecture, that the reason VirtualDOM is suddenly falling out of favour is a reaction against very bloated JavaScript applications and the complexity that underlies working with current popular frameworks and libraries. Some are starting to question whether we are working with solutions to actual problems faced or whether we've adopted approaches that were intended to solve a specific problem faced by some but are inefficient for simpler applications.

As always, be an engineer. Consider all relevant factors before choosing a set of tools or marrying yourself to one technology vs another.

[+] patrickthebold|3 years ago|reply
I think https://svelte.dev/blog/virtual-dom-is-pure-overhead might give you some answers to your question.

My very rough understanding is: It's nice to be declarative and just re-render everything on every state change. This is impractical to do with actual dom, but maybe works good enough with vDOM and dom diffing. Still, doing vDOM and them actual DOM updates is more work than just doing the DOM updates that are needed. And I guess tools like svelte let you be declarative and only make the necessary DOM updates while skipping the vDOM.

[+] hbrn|3 years ago|reply
The reason VDOM was desirable is that React's "View is the function of the State" paradigm has a great developer experience, and VDOM was just the easiest way to implement it without sacrificing performance too much.

Now that we played with the easiest implementation of V = f(S) for a few years, we're moving on to more complex implementations, which have their own benefits. Namely, less overhead and better DX.

Frameworks like Svelte are moving good chunk of state management accidental complexity out of your app code and into the framework itself, where it actually belongs (i.e. where it is essential).

[+] rmckayfleming|3 years ago|reply
It's easy to forget nearly 10 years on, but React came out when Backbone.js with mustache templates was rather common, and React was a LOT easier to manage. The other popular frameworks at the time were Ember and Angular 1, which were quite a bit larger/heavier. By comparison, React could be adopted in a much more incremental fashion. React was super easy to adopt (and it still is, but there's a lot more of an ecosystem around it now which makes it feel much more like a framework).
[+] huy-nguyen|3 years ago|reply
The author seems to suggest that React is reactive in the sense of “functional reactive programming” (a la RxJS) but React has never been “reactive” at all (see “scheduling” heading on https://reactjs.org/docs/design-principles.html).
[+] azangru|3 years ago|reply
> The author seems to suggest that React is reactive

The word "React" never appears in the README.

[+] ThePhysicist|3 years ago|reply
Personally I don't get why you wouldn't use JSX for such a tool. If you're building JS apps for production you'll invariably use a bundler like Webpack so transpiling JSX to JS is not an issue, and it makes Markup code in JS so much more readable.
[+] foobarbecue|3 years ago|reply
The self-fulfilling prophecy "you'll have to have a build step" makes me so sad.
[+] ilrwbwrkhv|3 years ago|reply
Yup it's ugly and tedious. Something like imba is far superior with vastly better ergonomics.
[+] nayroclade|3 years ago|reply
What exactly does this offer over, say, SolidJS, which also has reactivity without a virtual DOM, and has a much larger community, ecosystem, etc? As do several other frontend frameworks. Does the world really need another one, unless it can offer something substantially different?
[+] tambourine_man|3 years ago|reply
I’m always happy to see React alternatives but I’m not convinced HTML and CSS inside JavaScript was a good idea.
[+] sirsuki|3 years ago|reply
I tried reactivity once to help me understand the implementation details under the hood. I wrote https://fancy-pants.js.org/ for this where I attached mutation to scheduling a render cycle. But it doesn’t address rendering leaving that to the student.

Something that really fascinates me is the difference between diffing versus declaration of dynamic content. In React and Vue it is a runtime function to know what changed and how to apply it. In Ember and Svelte it is a compile time calculation based on markers in the template.

I guess it comes down to personal preference. I’m quite the fan of a declarative style template that gets converted/compiled to a machine under the hood instead of diffing at runtime.

[+] antihero|3 years ago|reply
Yeah the second I saw the string block I noped out. JSX works really nicely and I dislike weird template string stuff now. Same with vue.
[+] friedman23|3 years ago|reply
The alternative is a custom DSL for templating which I find much worse. Even CSS has a DSL for conditional and programmatic logic which I only use because of the immense performance benefits it brings.
[+] jfengel|3 years ago|reply
Certainly not in the form of strings, no. That's a nightmare of run-time debugging just to make sure the tags are all closed and you have the correct attributes.

Perhaps pair it with a typescript library for composing it. There's nothing sacred about HTML for describing the DOM, but that it what it was created for, and the language the browser will report it.

[+] thunderbong|3 years ago|reply
That ship has sailed long ago!
[+] bob1029|3 years ago|reply
This vDOM concept never really clicked for me. I always saw it as some sort of shiny feature that a web framework had to have in order to be considered for use during the last decade.

I've rolled a DIY web framework using websockets and a brutish technique where I simply set document.body.innerHTML to whatever the server pushes. Still haven't found a situation where this falls apart, but I am sure HN can invent a hypothetical that would make me ashamed of myself.

[+] jakelazaroff|3 years ago|reply
That won’t preserve things like event handlers and it will perform increasingly poorly as you need to render more often, but for simple use cases it’s probably fine!
[+] Jasper_|3 years ago|reply
The usual cases are scroll positions, selected text, form fields, event handlers, basically any state that isn't naturally captured in the HTML text. That's where the VDOM differ comes in handy, by modifying existing elements and keeping the structure similar.
[+] hbrn|3 years ago|reply
VDOM is just an implementation detail that you shouldn't care about at all.

But React team went big on advertising it as some kind of virtue, and a lot of gullible engineers bought that idea.

[+] romualdr|3 years ago|reply
This place if overcrowded with solution that provide the same benefits than yours, you should clearly put a section describing the benefits of "Why us instead of X" - because it's not clear what this project brings new to the table.
[+] toastercat|3 years ago|reply
On the contrary, open source projects are not products, and this one (like many) is free to use, evaluate, and permissively licensed. So I'd encourage anyone who works on a JS framework to do as you please, don't worry about JS-fatigued HN commenters, and share your work with the world if you think others may like it. :)
[+] jiyinyiyong|3 years ago|reply
While virtual DOM solution has problems, I believe Dioxus https://dioxuslabs.com/ can be a better solution than Solid/Svelte solutions. We should try to optimize it with macros and other memory techniques to make it fast, rather than giving it up.

People may hold opinion that Solid/Svelte are excellent. However that's going towards another direction. Virtual DOM decouples how you declare UI and how it's rendered/updated by framework. Solid/Svelte couple them.

[+] azangru|3 years ago|reply
> Reactivity Without Virtual DOM

I am confused. Why are the concepts of reactivity and of virtual DOM put together like this? Was Virtual DOM ever solving the reactivity problem?

[+] serverholic|3 years ago|reply
It looks like this guy has created multiple accounts and posted the same URL multiple times.
[+] spankalee|3 years ago|reply
I wish more libraries would user tagged template literals instead of strings with custom expressions.

Then template expressions are just JavaScript and the library doesn't have to implement it's own limited and slower subset, like this seems to do.

[+] dmak|3 years ago|reply
I only read the title, but how is this different than something like Svelte?