[HN Gopher] Cample.js: Reactivity without virtual DOM
       ___________________________________________________________________
        
       Cample.js: Reactivity without virtual DOM
        
       Author : Cample
       Score  : 40 points
       Date   : 2023-02-10 12:29 UTC (10 hours ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | spankalee wrote:
       | 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.
        
       | serverholic wrote:
       | It looks like this guy has created multiple accounts and posted
       | the same URL multiple times.
        
       | romualdr wrote:
       | 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.
        
         | keb_ wrote:
         | 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. :)
        
       | ribit wrote:
       | 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 wrote:
         | 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 wrote:
         | 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.
        
           | ribit wrote:
           | Sure, that's the most straightforward way to approach these
           | things, but doesn't this mean your elements don't have
           | persistent identity between two renders? Tracking elements
           | between renders is what allows animations and other nice
           | things. So it's not exactly the same.
        
             | spankalee wrote:
             | No, it's better. Retaining identity is _easier_ with such a
             | system.
             | 
             | You mark in the DOM where the expressions are, and on
             | updates instead of a vdom diff you check if the template
             | rendering to a DOM location is the same as before. If it is
             | then you just update the expressions. All the unchanged
             | elements stay the same, and sine you don't traverse the DOM
             | or a VDOM, the update is much faster.
        
       | nayroclade wrote:
       | 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?
        
       | bob1029 wrote:
       | 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.
        
         | Jasper_ wrote:
         | 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 wrote:
         | 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.
        
         | jakelazaroff wrote:
         | 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!
        
       | ThePhysicist wrote:
       | 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 wrote:
         | The self-fulfilling prophecy "you'll have to have a build step"
         | makes me so sad.
        
           | ThePhysicist wrote:
           | With JS modules it might be possible to just write JS code
           | and include it in your HTML directly, I'm not sure if I'd
           | recommend that though as performance might not be great as of
           | now, and there are still many other caveats. In a few years
           | this might be less of an issue though when HTTP/3 is widely
           | deployed and loading many tiny files instead of one big one
           | won't make that much of a difference.
        
             | foobarbecue wrote:
             | HTTP/2 already mostly solved that, as I understand it,
             | except for some retransmit issues that can't be fixed until
             | TCP is replaced with QUIC. Right?
        
           | andsoitis wrote:
           | For one, JS engines don't support TypeScript natively and it
           | turns out that many teams who build and maintain large,
           | ambitious SPAs think TypeScript is a productivity boost.
        
             | keb_ wrote:
             | Not everyone uses/prefers TypeScript, and not everyone is
             | on a team that builds and maintains a large ambitious SPA.
             | There's room for both frameworks like Next.js and small
             | libraries that work without build steps.
        
           | draw_down wrote:
           | Going without linting, testing (automated testing anyway),
           | type checking would make me a lot sadder.
        
             | foobarbecue wrote:
             | A build step is not required for any of that. I use
             | prettier and jenkins on a large js codebase that never gets
             | transpiled, packed, or minified.
        
               | draw_down wrote:
               | That's true, I guess you can just run those locally. But
               | if there's CI in the picture the "build step" is a fait
               | accompli, as far as setup and maintenance and so forth.
        
               | foobarbecue wrote:
               | Github runs jenkins. Jenkinsfile specifies tests and
               | linting. How would webpack make this easier?
        
               | draw_down wrote:
               | [dead]
        
           | postalrat wrote:
           | If you don't have a build do you just have a couple giant js
           | files you edit?
        
             | foobarbecue wrote:
             | No, you can use ES6 modules. They've been natively
             | supported by all browsers for years.
        
               | jakelazaroff wrote:
               | The problem is that this scales poorly as the depth of
               | your module tree increases -- your browser needs to
               | download and parse a module before it can start
               | downloading any modules it imports, which causes a
               | waterfall effect.
        
               | foobarbecue wrote:
               | Yeah. Can I put a file that imports all the modules at
               | the top of the tree and load them before the browser has
               | to parse anything else, to pre-cache? I haven't tried
               | this yet.
        
               | jakelazaroff wrote:
               | In theory, but "no bundle step" becomes a much less
               | attractive pitch once you have to start manually
               | maintaining something like that.
               | 
               | IMO the advantage of ES module support in browsers is not
               | needing to bundle in development (although with native
               | bundlers like esbuild this is less of an issue) and for
               | deploying small apps where the tree is shallow. If and
               | when your codebase starts growing, you should use a
               | bundler.
        
               | postalrat wrote:
               | ES6 modules and your entire source tree?
        
               | foobarbecue wrote:
               | Yeah. You're right, that is a bit of a problem. On first
               | load, this is 272 files. I'm checking it now for the
               | first time and most of them are loading sequentially
               | rather than in parallel, which is taking 3.7 seconds.
        
       | dmak wrote:
       | I only read the title, but how is this different than something
       | like Svelte?
        
       | azangru wrote:
       | > 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?
        
       | huy-nguyen wrote:
       | 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 wrote:
         | > The author seems to suggest that React is reactive
         | 
         | The word "React" never appears in the README.
        
       | a_c wrote:
       | 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
        
         | hbrn wrote:
         | 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).
        
           | Izkata wrote:
           | > and VDOM was just the easiest way to implement it without
           | sacrificing performance too much.
           | 
           | Kind of. Virtual DOM nodes are extremely lightweight compared
           | to real DOM nodes, so manipulating a VDOM to determine what
           | updates need to be done to the DOM, instead of doing all
           | interactions/comparisons directly with the DOM, had a big
           | performance boost.
        
         | gspencley wrote:
         | 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.
        
           | khmii wrote:
           | [dead]
        
         | patrickthebold wrote:
         | 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.
        
           | a_c wrote:
           | Thanks! This helped lot. Now having taking a gentle look at
           | svelte, I think it is very smart. Instead of diff-ing the
           | virtual component tree, it is maintaining a dependency of
           | statements behind the scene by providing a reactive
           | declaration. Upon each event, the re-run the whole tree of
           | statements, then update the DOM directly with the result of
           | those statements, hence no need heavy manipulation of DOM nor
           | diff-ing of large in memory object. I've only just started to
           | look at svelte though, so could be very wrong. But again
           | thank you so much for you pointer, everything just clicked
           | suddenly.
        
         | rmckayfleming wrote:
         | 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).
        
       | mrozbarry wrote:
       | 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!
        
         | rektide wrote:
         | The bottom half of this list doesnt seem remarkable to me.
         | Smaller DOMs like Deno.DOM[1] or jsdom also can do that: we
         | dont need a vdom to do that.
         | 
         | [1] https://deno.land/manual@v1.25.4/jsx_dom/deno_dom
        
           | mrozbarry wrote:
           | Of course you don't need the vdom for testing, but it's
           | typically a little lighter weight since the implementation of
           | the vdom would already be bundled in. That said people
           | typically reach for some special vdom assertion library
           | anyway.
        
       | kristiandupont wrote:
       | 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?
        
         | larsonnn wrote:
         | 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.
        
           | romualdr wrote:
           | You're correct, it's not new.
           | 
           | Still, the question remains, what's the improvement over
           | Svelte or SolidJS which doesn't use VDOM as well ?
        
           | richeyryan wrote:
           | Or there is Inferno which is VDOM based and outperforms
           | Svelte on most benchmarks. The whole narrative of "VDOM is
           | pure overhead" doesn't hold out in practice, and I suspect
           | really just an excuse to attack React and promote Svelte.
           | 
           | https://krausest.github.io/js-framework-
           | benchmark/2023/table...
        
           | nailer wrote:
           | Solid too. But yes Svelte seems to have been the current
           | thing for a few years now.
        
             | ergo14 wrote:
             | Lit also does fine without VDOM and has good performance
             | characteristics.
        
               | djbusby wrote:
               | RiotJS as well.
        
           | szastamasta wrote:
           | They did this while introducing a lot of compiler magic and
           | automatic dependency discovery that not always works. I'm not
           | sure I'm sold on it. Code you write is not code you execute.
        
         | fabiospampinato wrote:
         | 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).
        
         | ulizzle wrote:
         | 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.
        
           | jakelazaroff wrote:
           | That's true, but you can say the same thing about reactivity:
           | not having it is always faster than having it. These are not
           | zero-cost abstractions; we use them because the alternative
           | tends to be less performant at scale, but technically you can
           | always beat them by going in and manually updating the DOM
           | yourself.
        
           | dmitriid wrote:
           | No, it's not _always_ faster.
           | 
           | IIRC in a recent stream the author of Solid showed that it's
           | hard to beat a proper VDOM implementation when you have 1000s
           | of elements.
           | 
           | And most naive non-VDOM implementations will probably lose to
           | a good VDOM implementation.
        
           | password11 wrote:
           | > _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._
           | 
           | Is there some recent study showing evidence or analysis of
           | this? You're saying the main root cause of poor performance
           | is the diff burning up CPUs?
           | 
           | I always assumed applications run slowly because people are
           | overusing global (redux) state and every state change is
           | subscribed to by like 10 different components. And people
           | making 5 network calls before their component meaningfully
           | renders.
        
         | synergy20 wrote:
         | How is it different from svlete and solidjs? both are no-VDom
         | approaches.
        
         | andy_ppp wrote:
         | 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.
        
       | tambourine_man wrote:
       | I'm always happy to see React alternatives but I'm not convinced
       | HTML and CSS inside JavaScript was a good idea.
        
         | thunderbong wrote:
         | That ship has sailed long ago!
        
           | tambourine_man wrote:
           | It has not. I'm right here at land, don't intend to go and
           | there are dozens of us here :)
        
         | sirsuki wrote:
         | 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.
        
         | jfengel wrote:
         | 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.
        
         | friedman23 wrote:
         | 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.
        
         | antihero wrote:
         | 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.
        
           | tambourine_man wrote:
           | No JSX for me either. I want plain HTML, CSS and JavaScript.
           | All scoped within their files and domains.
        
             | antihero wrote:
             | I've found this to be needless indirection.
             | 
             | If your components are large enough to warrant this simply
             | break them down.
        
               | tambourine_man wrote:
               | Just gotta write your CSS carefully. It's not easy, it
               | takes time to learn, but so does the constant juggling
               | that is the React world. At least the first one is faster
               | and won't be out of fashion in 5 years, since it hasn't
               | been in a decade.
               | 
               | I also find separation of concerns conceptually more
               | sound and powerful.
        
               | phailhaus wrote:
               | React was created in 2013, so it has in fact been "in
               | fashion" for a decade now.
        
               | tambourine_man wrote:
               | Yeah, hopefully that trend is dying and we can get some
               | sanity back.
        
               | phailhaus wrote:
               | Not at all, React is still a juggernaut and the industry
               | standard. It is really, really good at what it does and
               | other libraries are often riffs on its design philosophy.
               | Even if React itself goes away for some reason, those
               | patterns are here to stay since it has left a permanent
               | mark on the field.
               | 
               | These complaints sound a bit like saying "man, compilers
               | are so complicated, hopefully this trend is dying and we
               | can get some sanity back."
        
               | tambourine_man wrote:
               | It's an interesting comparison. An optimizing compiler is
               | an incredibly complex beast that makes developer's life
               | almost incalculably better. Most of our stack would be
               | unfeasible to write and maintain in assembly. I'm not at
               | all sold that React remotely qualifies, in fact, I've yet
               | to see any benefits to developers or end users.
               | 
               | >it has left a permanent mark on the field
               | 
               | It sure has, an indelible stain
        
               | phailhaus wrote:
               | > Most of our stack would be unfeasible to write and
               | maintain in assembly.
               | 
               | The same can be said about libraries like React and
               | websites. Honestly, your position is completely untenable
               | because it's the classic "everyone is dumb except me." Ah
               | yes, all these million and billion dollar companies
               | decided to use React because they're bored and not
               | because it brings any value. You're the only genius, if
               | only everyone realized that the Ideal Website was just
               | handcrafted js.
               | 
               | There are thousands of websites written in React today,
               | and they bring value to their users. That's not
               | disputable. To suggest that there's no benefits is just
               | an astounding level of arrogance.
        
               | tambourine_man wrote:
               | I'm far from being the only one and it doesn't take a
               | genius to see that our industry is driven by far more
               | than objective value returned to developer or end user.
               | 
               | Just do a quick search on HN, Twitter, Mastodon. You'll
               | see that's actually not at all hard to find articles
               | questioning its effectiveness.
               | 
               | The epiphany I had a few years ago is that React is very
               | good for hiring, being hired, managing a team and has
               | very little to do with writing and maintaining a website.
               | At least that's what I tell myself to find some peace. If
               | you don't think the JS world is mad, I don't know if I
               | can convince you in a HN thread.
        
       | athenot wrote:
       | This is in the same vein as Imba, which their memoized DOM.
       | 
       | https://imba.io
        
       ___________________________________________________________________
       (page generated 2023-02-10 23:01 UTC)