[HN Gopher] VanillaJSX.com
___________________________________________________________________
VanillaJSX.com
Author : novocantico
Score : 497 points
Date : 2024-08-16 19:01 UTC (1 days ago)
(HTM) web link (vanillajsx.com)
(TXT) w3m dump (vanillajsx.com)
| arjvik wrote:
| What benefit does the virtual DOM add?
| spoiler wrote:
| DOM interactions (read, writes) are synchronous, they're very
| slow, and it must happen on the main thread. This can cause the
| browser tab to freezing if access and updates aren't carefully
| "curated" (ie you don't want to read-check-then-write in a
| tight loop; or even write too often, even if it's the same
| value).
|
| It can also simplify some stuff surrounding event handling (but
| that's not it's main goal I think)
|
| So people wrote various ways to defer/batch/denounce updates.
|
| Virtual DOM is a general solution/implementation. It's not the
| only one, but I think you always need at least a tiny runtime
| to avoid too much DOM access (ie Svelte, Solid JS are fairly
| minimal)
| meiraleal wrote:
| > but I think you always need at least a tiny runtime to
| avoid too much DOM access
|
| Unless you use lit-html, which has a very efficient diffing
| algorithm that only updates the nodes that have changed.
| smallnamespace wrote:
| How is that done without a vdom?
| meiraleal wrote:
| Lit-html uses template literals for that
|
| https://lit.dev/docs/libraries/standalone-templates/
|
| "lit-html lets you write HTML templates in JavaScript
| using template literals with embedded JavaScript
| expressions. lit-html identifies the static and dynamic
| parts of your templates so it can efficiently update just
| the changed portions."
| smallnamespace wrote:
| A a high level there's not much difference between
| template literals and JSX, they are both syntax-sugary
| ways to represent trees of essentially function calls.
|
| > efficiently update just the changed portions
|
| Since actually applying each change to the real DOM is
| too slow, the only way to efficiently update is to batch
| changes and then apply the delta to the actual DOM.
|
| That means we need to keep track of some state, namely
| the previously applied state and the current goal state,
| which you then compare.
|
| Now, you may have noticed that we've just independently
| invented the concept of diffing. And the extra state that
| needed to be tracked can be given a spiffy name, like
| "virtual DOM", since it's like the DOM, but not the real
| thing.
|
| So, I'm quite unconvinced by Lit-html's claim that they
| are able to efficiently mutate the DOM without using a
| vDOM anywhere.
|
| Either their method is not efficient (for example it
| falls over for rapid updates), or there is a data
| structure under the hood that is analogous to a vDOM,
| even if they prefer to give that data structure a
| different name.
| meiraleal wrote:
| Oh well, we gotta thanks the great developers of Lit-html
| for making it transparent then. And a lot faster than
| React.
|
| https://krausest.github.io/js-framework-
| benchmark/current.ht...
| smallnamespace wrote:
| Yes, looking it into it more, Lit-html is doing a few
| things to make it all work:
|
| 1. It leans on support for the <template> element from
| browsers to hold fragments of HTML
|
| 2. For most use cases, it has a more restricted
| programming model compared to React or other vdom
| libraries, because templates are not allowed to change
| the shape (the tree structure of nodes) of the templated
| DOM.
|
| 3. For some cases where you want it to act more like
| React (for example, dynamically picking an HTML tag) you
| must use other mechanisms such as unsafeStatic. The docs
| explicitly tell you this immediately triggers a re-render
| = slow.
|
| So I guess that answered my own curiosity: the vDOM is
| mostly replaced by a collection of static templates that
| don't need to be diffed, because the onus is on the dev
| to write DOM fragments where the tree does not change.
|
| This is a more restrictive model that what React gives
| you, where you can generate any fragment tree, including
| ones with different shapes, entirely programatically.
|
| If you do want the tree's shape to change, then lit-html
| isn't promising you good performance. You'll need to use
| methods like unsafeStatic which are slow. All in all,
| this is pushing more work off onto the developer.
|
| Is this a good tradeoff? I think for most websites you
| can probably work within Lit's programming model. But the
| benchmarks you yourself linked points to many, many vDOM
| libraries that are about as performant as Lit (including
| React, whose main downside somewhat more memory usage)
| and has a more convenient React-like programming model.
| meiraleal wrote:
| Thanks for the comprehensive analysis, quite interesting.
|
| I disagree about the trade-off in convenience tho, React
| programming model (especially related to managing state)
| is quite confusing, verbose and error-prone.
|
| Multiple useless re-renders are the norm.
|
| useEffects inside the body of functions a very poor way
| to manage the lifecycle of a component and this is way
| simpler with Lit.
|
| All in all, just for it to be more like React pre-15 I
| would choose Lit.
| samwillis wrote:
| The virtual dom makes implementing a declarative templating
| system easer, and declarative templates are easer for a
| developer to reason about, and less error prone, than having to
| mutate the dom directly.
|
| People often mistakingly describe the vdom as faster than the
| dom, this is incorrect. It would be faster than throwing away
| the whole components dom and rebuilding, so the same templating
| code building a new dom, rather than a vdom that's then diffed.
| Hand crafter mutations will be faster than a vdom diff, simply
| because the computer is doing les work, however much more error
| prone.
| spoiler wrote:
| > People often mistakingly describe the vdom as faster than
| the dom, this is incorrect.
|
| You'll get better performance with _carefully crafted_ DOM
| access, but that's easier said than done, especially on a
| larger applications.
|
| vDOM takes care of the "carefully crafted" part with some
| trade offs, especially if it also defers rendering and
| doesn't wccess the DOM on every update.
|
| So yes, it's easier to write declarative UIs with it, but
| it's also there to address common performance issues with
| unchecked/eager DOM access. Even if you don't throw away the
| whole tree and insert a new one, it can be very slow. Just
| _reading_ from the DOM is slow _and_ everything stops while
| that's being done too.
| miki123211 wrote:
| Virtual DOM is to classical JS what garbage collection is to
| malloc and free.
|
| Garbage collection is less efficient, but it is sometimes
| very difficult to figure out exactly when a piece of memory
| stops being used, which leads to use-after-free, double-free
| and memory leak bugs.
|
| Same goes for classical UI approaches. In classical UI, most
| pieces of state are kept in at least two places, once in code
| and at least once in the DOM.
|
| For example, in a shopping cart, the total might appear three
| times, implicitly in the code (as a function that sums the
| prices of all the items), once as the label of the "open
| cart" button in the navbar, and once as text in the "your
| cart" modal, which that button shows or hides. THe cart may
| be modifiable from different places, the cart modal itself,
| product pages, product collection pages, order history (when
| re-ordering recently purchased items) etc.
|
| In the classical approach, you need to make sure that all
| modifications to the cart accurately change the state in all
| three places. You also need to ensure that if you remove a
| product from the cart using the modal and you're currently on
| a page that lets you order the product in any way, the
| "remove from cart" button on that page needs to turn back
| into "add to cart", and there may be hundreds of different
| such buttons, which the cart modal needs to handle somehow.
| It is very easy to make mistakes here and have the state in
| the code (array of products) fall out of sync with what the
| user sees on the page.
|
| In React, there's just one array of products, one function to
| calculate the total, and a lot of places in the code that use
| this array. WHenever the array changes, the pieces of the
| page that rely on it automatically re-render, while
| everything else stays the same. There's no way for the UI and
| the array to fall out of sync, and there's no need to track
| where the array is being used and where it's being modified.
| itsgabriel wrote:
| I don't quite get how this reactivity is only possible with
| a VDom, for example Svelte
| https://learn.svelte.dev/tutorial/updating-arrays-and-
| object... also allows you to update the UI on changes to
| the array.
| miki123211 wrote:
| To extend the malloc versus GC metaphor, Svelte here is
| like Rust, it has really good developer experience while
| still giving you most benefits of Virtual DOM.
| edflsafoiewq wrote:
| It enabled a style of view library where you write immediate-
| mode type code that always recreates a whole component from
| scratch, versus having to write finicky code that both creates
| and then updates pieces of the page as state changes (dirty
| tracking, etc). Behind the scenes, you're creating the vDOM
| from scratch, which is diffed against the actual retained-mode
| DOM, and then only the pieces that are different are updated.
| ProofHouse wrote:
| Slows down your app too, sometimes. Depends how well you can
| work with and mutate a DOM, but if all things equal no VDOM is
| always faster cause no diffing.
| ProofHouse wrote:
| A lot of people can benefit from offsetting mutations with
| rAF and dbl rAF and batching reads/writes (FastDOM), before
| needing or considering a VDOM. VDOM came to prominence
| because of REACT and then started becoming used even when it
| wasn't needed. It does serve a purpose and scenario when
| needed, tho
| __s wrote:
| With vDOM I could say `x = JSX` then cache that in state,
| inserting it in multiple places. Switching to Solid you have to
| make sure to use `x = () => JSX` & there's some mental model
| adjustments since logic outside JSX isn't reactive
| acdha wrote:
| If you couldn't efficiently batch updates, a vDOM could avoid
| repetitive updates in close succession, especially on IE6 (the
| browser React was designed for).
|
| If you can control your app's structure, it primarily adds
| significant increases in the RAM and CPU required for your app
| and slows load time because you are using a huge amount of
| JavaScript to emulate the carefully tuned C++ code built in to
| the browser. If you notice, most of the benchmarks from when
| React launched claiming performance wins were compared to
| heavyweight frameworks or complex jQuery plug-in combinations
| where a single user interaction might trigger cascading updates
| forcing the browser to rerender things which didn't change
| along or to reflow multiple times in cascading update-measure-
| update chains. Pure DOM implementations were always faster,
| often by multiple orders of magnitude and once you could drop
| IE6, and then IE11, the DOM APIs and CSS were rich enough that
| much of the library code is now a net negative as well (e.g.
| people used to use complex code trying to build layouts which
| CSS grids solved).
| config_yml wrote:
| Reminds me of Action Script 3 which had XML at the core of the
| language. It was a fun language to work with, but famously failed
| to become ES4. Oh well, took us 10+ years to arrive close to that
| with Typescript and JSX.
| quink wrote:
| https://en.wikipedia.org/wiki/ECMAScript_for_XML - Firefox had
| it too, but people at large just didn't want it, so it got
| removed. It got disabled for web pages with the release of
| Firefox 17, 6 months prior to the first release of React.
| sltkr wrote:
| Personally I never heard about it. So it might not be that
| people didn't want it, but that it wasn't promoted much.
|
| Also, it sounds like the only browser to ever support it was
| Firefox? That was probably much more of a limiting factor for
| adoption.
| kibibu wrote:
| If you weren't coding for the flash platform you would have
| easily missed it.
|
| Its a shame, E4X was really nice
| mhitza wrote:
| People didn't want it because browsers didn't support it
| (except FF, as you noted). Some of us had our fingers crossed
| that other browsers would pick it up.
| shove wrote:
| I don't recall being able to construct XML inline like this
| unless maybe that was a Flex server thing?
| dugmartin wrote:
| It was an extension to ES4 called E4X - it allowed inline xml
| along with a new xml data type. More info here:
| https://evertpot.com/ecmascript-4-the-missing-version/
| noduerme wrote:
| I think parent must be referring to Flex components. AS3
| itself had an XML library which I recall being absolute hell
| to work with. The better way to send things over the wire
| with AS3 was with AMF.
| theturtle32 wrote:
| Nope. I worked with Flex and it's MXML files extensively.
| But the parent is talking about E4X, which was an extension
| to ECMAScript that allowed you to use XML elements inline
| with JavaScript in a manner VERY similar to how JSX is used
| today. It also included the ability to much more easily
| query and otherwise work with those XML document trees in
| native JavaScript.
| config_yml wrote:
| No, writing XML was the declarative part of Flex (like
| HTML), but AS3 had it's own XML type so you could do things
| like this:
|
| var data:XML = <foo><bar>hello</bar></foo>
|
| and then data was an object instance like you'd expect
| zoogeny wrote:
| I don't recall being able to do the XML construction inline
| either, but that just might be my memory.
|
| However, the XML selector syntax was a godsend. Recursively
| parsing an XML tree is really a pain. E4X would allow you to
| do things like: var foo =
| someXml..childNodes.@attribute;
|
| I'm not even sure if that would work actually. There were a
| bunch of operators for doing things like getting a collection
| of children that all had the same tag so you could work with
| XML like: <someXml>
| <intermediateNodeYouWantToSkip> <childNode
| attribute="1" /> <childNode attribute="2" />
| <childNode attribute="3" /> <unrelatedNode />
| </intermediateNodeYouWantToSkip> </someXml>
|
| Another post here said people didn't want it, but I don't
| think that was the real reason it was dropped. There was a
| lot of drama at the time about Flash in general and a massive
| debacle about EcmaScript 4 (which ActionScript more or less
| adopted). There was also the whole XHTML thing happening.
|
| Basically JSON as a format won out over XML and ES4/XHTML
| were ditched. Frankly, a world that revolved around XML/SOAP
| would have been a nightmare, so I guess killing off the easy
| processing of XML in JavaScript helped to stave off that
| potential future. XSS, XSLT and E4X were all casualties.
| waynenilsen wrote:
| This plays very nicely with the locality of behavior model of
| htmx
| sophiebits wrote:
| These examples are cool but I think it's important to note that
| none of them show components whose props can change over time,
| since that ability doesn't seem to be modeled at all. Clever if
| you don't need that but I'm having trouble seeing how it would
| scale to more complex apps.
| numpad wrote:
| Maybe I'm missing something, but how would this prevent you
| from using setTimeout/setInterval? But I agree that these
| projects often work great in small use cases, but quickly
| crumble under "real world" scenarios.
| novocantico wrote:
| I admit that the two most complex "interactive apps" I've
| built with this are not that complex according to many
| standards:
|
| * https://www.immaculatalibrary.com/books.html (src = https:/
| /github.com/sdegutis/immaculatalibrary.com/blob/main/...)
|
| * https://www.immaculatalibrary.com/prayers/ (src = https://g
| ithub.com/sdegutis/immaculatalibrary.com/blob/main/...)
| _heimdall wrote:
| I'd be hesitant to run something like a 30fps render loop in
| a web app. Its been years since I last saw or tried that in a
| real world app but it didn't end well for performance.
|
| Your best bet would be to queue up specific UI changes that
| need to be made as diff's rather than checking the entire UI
| state. At that point, though, you might as well run them
| immediately as the change is needed.
|
| If that was still a perf problem you would end up chasing a
| very complex solution like react fiber to partially update
| the UI on a loop while periodically pausing for user events.
| sophiebits wrote:
| Sure, if you blow away the entire app on every state change.
| But that would lose not only state defined in components
| (like `i` in ClickMe) but also all state implicitly stored in
| DOM elements (selection, focus, scroll position, input value,
| media playback).
| throwitaway1123 wrote:
| I would almost certainly never implement a UI as a render
| loop, but if you wanted to go down that path
| requestAnimationFrame is a much more idiomatic way to do it
| if you want to match the user's display refresh rate.
| hellojebus wrote:
| I'm by no means an advocate of this library, and never plan to
| use it, but to support component props that trigger rerenders,
| a'la React/Vue, I would use JS Proxies here. Wouldn't be that
| hard to implement.
| sophiebits wrote:
| How would you suggest using Proxy?
| novocantico wrote:
| The technique I used here and in all my browser-side code is
| the exact same technique used by VS Code internally, and it
| scales very well. The only difference in my code is it's more
| concise than writing 10 lines to construct and setup a DOM
| element the typical way.
|
| Honestly, the real interesting part about my framework is
| _literally everything else_. Returning strings from JSX on the
| ssg-side; being able to import raw source directories and
| manipulate string|Buffer at ssg-time; the extremely efficient
| and lightning fast module system I wrote on top of chokidar and
| swc; probably more I 'm forgetting, but basically the JSX-as-
| DOM is only the most _visually_ interesting part. But really
| just a party trick.
|
| [edit] Case in point: the source code to vanillajsx.com is
| extremely concise and clear and short, I literally wrote the
| whole thing today with zero deps (besides imlib), and the JSX-
| as-DOM demos are the least innovative part of it:
| https://github.com/sdegutis/vanillajsx.com/tree/main/site
| novocantico wrote:
| I just added a more complex todo app to the bottom of the
| page. So it should give an idea of how a more complex
| hierarchy can respond to events elsewhere in the hierarchy
| and update themselves and each other accordingly.
| tombl wrote:
| Yup, in order to scale this approach to any real size (and
| still have confidence that everything is working together like
| you expect), a proper reactivity solution is needed.
|
| For those that appreciate this approach of JSX returning
| concrete DOM elements, Solid works exactly like this, with the
| addition of a proper reactivity layer.
| ibash wrote:
| People forget what problem the virtual dom and react is supposed
| to solve.
|
| No better article than this:
| https://blog.vjeux.com/2013/javascript/react-performance.htm...
| Spivak wrote:
| And then Svelte showed that you could avoid all that with a
| compilation step and live update the dom efficiently.
|
| https://svelte.dev/blog/virtual-dom-is-pure-overhead
|
| React is also at the point where re-rendering the whole app is
| a fiction the library maintains for you while being smarter and
| doing less, why not go the whole way?
| ibash wrote:
| Agree, react is way too bloated right now. The original idea
| and first versions were great.
| culi wrote:
| The original idea and first versions were extremely
| inefficient and unscalable
| Aeolun wrote:
| And then SolidJS showed that you could do the same thing even
| without a compilation step.
| guax wrote:
| For me is because is hard to remember that problem while
| dealing the the ones react brings.
| insane_dreamer wrote:
| There are plenty of cases where optimizing for performance
| isn't necessary. This is where React is not worth the extra
| headache and complexity.
| presentation wrote:
| React is set to become much less complex as a user once the
| react compiler is in place and if you use server
| components/actions; in my product we've already basically
| eliminated 95% of useEffect calls, almost all data fetching,
| client side state management with the current gen tools, and
| once the compiler is in then all memoization will be gone
| too.
|
| You still end up with the bloated bundle size but with one of
| the more modern react alternatives you can eliminate that
| too. So at least for me, I don't mind the build complexity
| for the power I get; especially now that node itself is
| supporting typescript, the build side is getting simpler to
| set up as well.
| mbivert wrote:
| (honest question, not trying to be snarky) Do you have one
| (many would be great) use cases where the practical gain of the
| virtual DOM solutions have a genuine impact?
|
| I'm asking because, many of React (or friends) introductory
| material naturally focus on building things like TODO lists or
| Tic Tac Toe; while those offer insights into how to work with
| React (& cie), they're not showcasing cases where the
| performance gains are perceptible, and IMO not even cases where
| the "organizational" benefits of such libraries are salient.
| eterps wrote:
| This question is crucial to understanding the true value of
| React and virtual DOM technologies.
|
| While there's no doubt that React and virtual DOM offer
| advantages, it's essential to clearly demonstrate where and
| how these benefits manifest in real-world applications.
|
| > _they 're not showcasing cases where the performance gains
| are perceptible_
|
| According to this commenter, it's not even about the
| performance gains:
|
| https://news.ycombinator.com/item?id=41271272
|
| > _and IMO not even cases where the "organizational" benefits
| of such libraries are salient_
|
| Apparently, that is what it ultimately boils down to:
|
| https://news.ycombinator.com/item?id=41271367
| mbivert wrote:
| > _While there 's no doubt that React and virtual DOM offer
| advantages, it's essential to clearly demonstrate where and
| how these benefits manifest in real-world applications._
|
| Definitely; it's a struggle to find precise, concrete
| arguments in this direction. And there are many good
| reasons to be conservative: e.g. inheritance-based OO was
| sold with "VW inherits Car"; looks great on paper, but not
| as much in front of real-world issues.
|
| > _Apparently, that is what it ultimately boils down to:_
|
| If so, I'd be left wondering how much of this is actually
| caused by a lack of discipline, as seems to be for example
| indicated by the "dumb reflows" issues.
| NohatCoder wrote:
| Obviously this always depends on what code you compare it to.
| I don't think there can be much doubt that a well written
| performance oriented framework-free implementation is in
| practice always going to be faster than anything using
| virtual DOM, as one can update simply the parts that need
| updating without creating the virtual DOM in the first place.
|
| If you assume programmers who don't know what they are doing
| it is a very different question. Some people will manage to
| make a train wreck both with and without a framework. But if
| we assume that there is a skill level where people will
| manage to make something useful with a framework, but not
| without it, or vice versa, then I really do not know which
| way it swings.
| ibash wrote:
| Yes:
|
| One project I worked on was a BI tool with a fair amount of
| complex state. Before we introduced react we were using
| backbone, event listeners, and managing dom state ourselves.
| With react we made it declarative, which simplified things.
|
| Another project was an email client with a lot of complex
| state and caching. That started with and continued to use
| react so I don't have a direct performance comparison. But
| again, managing the state manual would have been a nightmare.
| cribbles wrote:
| These "what ifs" are kinda funny because the origins of JSX can
| be traced back to Facebook's XHP[1], which took explicit
| inspiration from E4X[2], an early JS standard that looked and
| behaved similar to the library described here.
|
| [1] https://engineering.fb.com/2010/02/09/developer-
| tools/xhp-a-...
|
| [2] https://en.m.wikipedia.org/wiki/ECMAScript_for_XML
| spankalee wrote:
| E4X had the unfortunate downside of returning actual DOM
| instances, which needed to be updated imperatively. That's why
| JSX eclipsed it, and there hasn't been a serious proposal for
| HTML templating in JS since then.
|
| But maybe we can revive the general idea with a modern take:
| https://github.com/WICG/webcomponents/issues/1069
| lolinder wrote:
| > had the unfortunate downside of returning actual DOM
| instances, which needed to be updated imperatively.
|
| Isn't this what we have in TFA?
| bastawhiz wrote:
| Yes, for elements. The project here also supports a notion
| of components, though, which E4X didn't contemplate.
| olliej wrote:
| Also E4X was only ever implemented in Firefox, never really
| got traction even in Firefox.
|
| But even considering the single implementation problem, it
| also was just not a good language model, nor was it well
| specified or defined and it brought with it a pile of weird
| baggage and complexity.
|
| Then because it was The Future there was no real thought into
| proper interop with JS (it was essentially a completely
| independent spec so adopted general syntax but specified in a
| way that meant JS could not simply adopt that syntax).
| kreetx wrote:
| With "imperatively" you mean that the user of the templating
| system has to do it imperatively, and that is bad? Asking
| because imperative updates seem to be the way to go within
| the implementation, instead of creating new instances of
| elements every time.
| Sephr wrote:
| > E4X had the unfortunate downside of returning actual DOM
| instances, which needed to be updated imperatively
|
| Firefox never shipped the optional E4X DOM APIs. I wrote a
| polyfill for them at the time.[1]
|
| 1. https://github.com/eligrey/e4x.js/blob/master/e4x.js
| SkiFire13 wrote:
| > which needed to be updated imperatively
|
| VanillaJSX seems to suffer from the same problem though.
| megaman821 wrote:
| There are separate proposals from web components that get rid
| of imperative updates.
| https://eisenbergeffect.medium.com/the-future-of-native-
| html...
| olliej wrote:
| Fun fact, E4X is the reason JavaScript has 'for(of)' instead of
| 'for each' (the reason we didn't get 'for (:)' is even dumber -
| it would conflict with ':type' annotations a few TC39 members
| were convinced would magically be in the language)
| rlt wrote:
| Like the type annotations that are now in TypeScript?
| olliej wrote:
| Yup, that were in typescript, pascal (and rust, etc when
| they came out).
|
| But there was no real progress after years of them pushing
| this syntax, but failing to actually define a type system
| that was coherent, or a model that would allow it.
|
| As a result I proposed `for (of)` largely to prevent sane
| enumeration from being blocked on the intransigence of two
| people.
|
| It's also worth noting that for(:) enumeration would not
| even preclude their syntax - it's certainly not
| grammatically ambiguous - and most real world code in
| languages that support enumeration directly and support
| inference doesn't explicitly specify the types , so the
| ugliness of `for(let a:type:expression)` would have be rare
| anyway.
|
| _shrug_
|
| Given that ECMA literally killed E4X a few years later the
| blanket ban on "for each" or "foreach" (because it would be
| "confusing" in E4X) is arguably worth than for(:), but
| again _shrug_
| IshKebab wrote:
| There is a proposal to add them, though it does seem to be
| stalled.
| olliej wrote:
| There were proposals almost 2 decades ago. They've never
| gone anywhere because proponents of type specifiers don't
| want to do the necessary corollary: specifying the type
| system.
|
| Typescript and similar can do it because they don't have to
| specify the type system, and can't change it in meaningful
| ways over time. Things in the language standard cannot be
| easily changed, if they can be changed at all.
| IshKebab wrote:
| > the necessary corollary: specifying the type system.
|
| It's clearly not _strictly_ necessary though. Python has
| shown that.
|
| I mean I agree it is pretty mad to just say "you can
| write types but they mean whatever" but surprisingly in
| practice it seems to work ok.
| spullara wrote:
| I was bummed when they removed E4X from the browser
| implementations.
| novocantico wrote:
| Thanks for taking some interest in my project. It came from being
| frustrated with the state of SSGs over the past 10 years. I
| mostly just make static websites, and I wanted something that was
| simple and intuitive to me, and JSX seemed like a great fit. But
| I got very tired of the disproportionately scaled complexity of
| JSX frameworks like React. Long story short, I made an SSG that
| just renders JSX as strings. It was natural to extend that to the
| browser to just render JSX as DOM elements. And in a few cases
| (mostly layout) it lends well to shared components. Overall I'm
| happy with what I came up with, although some of it is admittedly
| a little hacky, and IDE support isn't as good as it could be.
|
| [edit] Oh also, this solution works really well for SEO. That's
| another problem I didn't find solved well in other JSX
| frameworks.
| thelastinuit wrote:
| not the hero we deserve but the villain we need
| hyperhello wrote:
| What I'm seeing here is not new. It's this vanilla pattern but
| with enough back support to leave off the framing and get the
| syntax highlighting:
|
| Var button = html('<button>im a button</button>');
|
| The html() function is trivial, but it just doesn't _feel_ like
| real programming to do this, even though there's nothing else
| to it in the end.
| hyperhello wrote:
| Downvote me but tell me why. The example is using .onclick,
| .textContent, etc in a completely vanilla way. I'm just
| pointing out you can get all the way vanilla and it still
| works. What's the issue?
| novocantico wrote:
| lolinder explained it well in here
| hyperhello wrote:
| He did, and he pointed out the point is just IDE support
| so it has typing and autocomplete and syntax
| highlighting. Thanks, we agree!
| mock-possum wrote:
| Tagged template literals for html view templating is what I
| LOVE about Lit and lit-html. It's JavaScript you can run
| natively in browser, no server or pre processor/build step
| necessary.
| fredmerc wrote:
| A JSX for Django server side would be cool.
| WesleyJohnson wrote:
| How would you envision this working?
| megaman821 wrote:
| Not exactly JSX, but I came across a package django-
| cotton[https://github.com/wrabit/django-cotton], that is html
| syntax first components.
| shepherdjerred wrote:
| Just curious, have you seen Astro? I feel like it's the perfect
| SSG, but maybe you have some reservations that VanillaJSX
| solves.
| newzisforsukas wrote:
| astro is nearly, if not as, "complex" as react, no?
| molszanski wrote:
| As person who has been doing "react" since 2016 I would say
| that it removes so much of the "react" complex BS that I am
| surprised it is not x100 times more popular.
|
| We've recently moved one service from next to Astro and it
| was just removing a ton of boilerplate and "dance around"
| code.
| FractalHQ wrote:
| That's how I felt going from Astro to Sveltekit, but
| that's a shorter distance to travel.
| molszanski wrote:
| Oh, but you are moving out of React. And svelto IMO is
| waaay friendlier and "sane" than "typical" react. Svelte
| reactive model (observables and computed) are very
| friendly and simple to use.
| shepherdjerred wrote:
| It doesn't really make sense to compare React to a static
| site generator.
| _heimdall wrote:
| I'm a big fan of Astro, though I could see it being a bit
| more of an adjustment for JSX users than Svelte users since
| Astro's syntax was originally based on Svelte.
|
| That said, JSX can be used easily with Astro as long as you
| get used to at least a bit of The `.astro` syntax for wrapper
| components and pages/layouts.
| vips7L wrote:
| SSG?
| blackeyeblitzar wrote:
| Static site generator, apparently
| novocantico wrote:
| For all "have you tried ___" questions, the answer is the
| same. I've been trying all these new techs for the past 10-15
| years, regularly, as soon as they come out, for the first few
| years with much with excitement, and later with
| disillusionment and less regularity.
|
| Another user below said
|
| > We've recently moved one service from next to Astro and it
| was just removing a ton of boilerplate and 'dance around'
| code.
|
| And I get why it happens. When you first try out a new
| framework, you _allow_ yourself to learn and add its inherent
| complexity, _knowingly and intentionally_. You say to
| yourself, "it's part of the dream, it's going to work out;
| there's a vision, just trust the process." This is true with
| literally all frameworks.
|
| But they never deliver. The complexity is never worth it, and
| in the end, the intentionally added complexity is always
| intentionally and gladly removed when it becomes clear that
| it was _unnecessary_ complexity. This is what I am glad to
| have learned so thoroughly that I no longer try to learn new
| frameworks when I initially see its complexity, imagine
| adopting it in view of my experience, and recognize that its
| almost always not worth it.
|
| Look at the code on vanillajsx.com. Besides JSX and types,
| it's plain JavaScript and DOM manipulation. Translating it to
| document.createElement would add almost no lines of code.
| There's no unnecessary complexity. That's the whole point of
| the site. The simplicity of discovering and removing
| unnecessary complexity is wonderful and refreshing, and I
| think a lot of people agree.
| dimal wrote:
| I like your thinking. Things have gotten far more complex
| than they need to be. We've been piling abstractions on top
| of abstractions for too long and there needs to be a
| culling. If we get rid something that we really did need,
| that's better than the alternative. It's best now to ditch
| it all and see what we really need.
| samtheprogram wrote:
| So, I take it you haven't tried Astro then?
| shepherdjerred wrote:
| I think you're misunderstanding the poster you quoted.
| They're indicating a positive experience with Astro.
|
| > We've recently moved one service from next to Astro and
| it was just removing a ton of boilerplate and 'dance
| around' code.
|
| ---
|
| > And I get why it happens. When you first try out a new
| framework, you allow yourself to learn and add its inherent
| complexity, knowingly and intentionally. You say to
| yourself, "it's part of the dream, it's going to work out;
| there's a vision, just trust the process." This is true
| with literally all frameworks.
|
| I am quite picky and have strong opinions. I've used Astro
| for more than a year and still love it. There is complexity
| (especially if you use SSR), but for the use case of "I
| just want a static site" it is wonderful.
|
| > Look at the code on vanillajsx.com. Besides JSX and
| types, it's plain JavaScript and DOM manipulation.
| Translating it to document.createElement would add almost
| no lines of code. There's no unnecessary complexity. That's
| the whole point of the site. The simplicity of discovering
| and removing unnecessary complexity is wonderful and
| refreshing, and I think a lot of people agree.
|
| I don't disagree, but this doesn't replace what you might
| want for SSG. For one, this requires JS on the client.
| Astro compiles to static HTML despite using JSX-like
| syntax.
|
| As an example, here's my Astro site and source code:
|
| * https://sjer.red/
|
| * https://github.com/shepherdjerred/sjer.red
| novocantico wrote:
| My framework (imlib[1]) is actually more of a framework
| akin to Astro than what's showcased on vanillajsx.com,
| which itself is built with imlib.
|
| It just runs your code in a node.js process, and
| translates your JSX expressions into jsx() calls. On the
| node.js side[2], jsx() returns a string from its
| tag/attrs/children. On the browser side[3], jsx() returns
| DOM elements.
|
| Combined with a little bit of architecture, it becomes
| something extremely well suited to creating static sites.
| I guess SSG is an outdated term now, maybe it's a
| framework? Or a platform?
|
| In any case, it seems to do something similar to Astro,
| but in a significantly simpler way. The only "bundle" it
| needs in the browser is /@imlib/jsx-browser.js [4] which
| in itself is just jsx-dom.ts (its impl is overridable by
| the "framework" user). And on the node.js side, it's
| implemented as a very small "vm" of sorts [5].
|
| I'm not against Astro, I just get all the same benefit
| people here are saying Astro has, but with orders of
| magnitude more simplicity imo.
|
| I've used imlib to make a relatively large website [6],
| in fact imlib was developed as this website and extracted
| from it over the past year. I have absolutely no
| difficulty breaking down my site into various reusable
| and encapsulated JSX components, both on the ssg-side and
| the browser-side. Development time is lightning fast. IDE
| support is essentially automatic. The site loads
| instantaneously in the static parts, and as quickly as
| reasonable in the dynamic parts.
|
| [1] https://github.com/sdegutis/imlib
|
| [2] https://github.com/sdegutis/imlib/blob/main/src/jsx-
| strings....
|
| [3] https://github.com/sdegutis/imlib/blob/main/src/jsx-
| dom.ts
|
| [4] https://vanillajsx.com/@imlib/jsx-browser.js
|
| [5] https://github.com/sdegutis/imlib/blob/main/src/runti
| me.ts
|
| [6] https://github.com/sdegutis/immaculatalibrary.com
| shepherdjerred wrote:
| Thanks for taking the time to clarify & not getting
| hostile :)
|
| I'll look into imlib a little more.
| todotask wrote:
| Large WASM payload on your site could be optimized.
| AltruisticGapHN wrote:
| Have you looked into lit-html?
|
| Coming from Vue I was really surprised it does a lot of what
| Vue templating does, including attaching events, with just
| vanilla JS templates. And when you use VSCode lit extension,
| you get syntax highlighting and full type checking inside the
| templates.
|
| I learned about lit-html after a tweet from Marc Grabanski,
| where he said he used lit-html with vanillajs, not Lit.
|
| After some experimenting I found it works great and it seems
| like you are trying to solve something very similar.
|
| When you use the lit-html template package you can do basically
| evetything that is described in the Templates chapter
|
| https://lit.dev/docs/templates/overview/
|
| ... without all the other abstraction of components that are
| part of lit-element.
|
| https://lit.dev/docs/libraries/standalone-templates/#renderi...
| dimal wrote:
| Love the idea. FYI, on your demo page, the todo app is 404. And
| you might want to spell out static site generator instead of
| saying "SSG" on your docs. I didn't know what SSG was, even
| though I've used static site generators. I had to ask the AI.
| nashashmi wrote:
| I wonder what The examples would look like in ECMAscript 5.
| spankalee wrote:
| Returning actual DOM nodes entirely blunts the big advantage of
| JSX (and non-JSX libraries like Lit) - which is their immediate
| mode style API, and UI=f(state) model.
|
| 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.
|
| All the examples here use imperative DOM APIs to do updates, like
| with this: function TodoInput(attrs: { add: (v:
| string) => void }) { const input = <input /> as
| HTMLInputElement; input.placeholder = 'Add todo
| item...'; input.onkeydown = (e) => { if
| (e.key === 'Enter') { attrs.add(input.value);
| input.value = ''; } }; return
| input; } class TodoList { ul = <ul
| class='todolist' /> as HTMLUListElement; add(v: string)
| { const item = <li>{v}</li> as HTMLLIElement;
| item.onclick = () => item.remove();
| this.ul.append(item); } }
|
| Avoiding those `input.onkeydown = ...` and `this.ul.append(item)`
| cases, and instead just iterating over items in your template, is
| probably the main benefit of a VDOM.
|
| (The problem with VDOMs is that diffing is slow, a problem solved
| by using templates that separate static from dynamic parts, like
| Lit - a library I work on).
| recursive wrote:
| > 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)
| spankalee wrote:
| 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?
| lolinder wrote:
| 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.
| _heimdall wrote:
| 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.
| lolinder wrote:
| 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.
| recursive wrote:
| 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);
| esprehn wrote:
| 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.
| Izkata wrote:
| 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).
| ericmcer wrote:
| 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.
| acdha wrote:
| 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.
| MrJohz wrote:
| 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.
| JasonSage wrote:
| I agree with the sibling comment that this really depends on
| the user. To take a different approach: JSX is just a different
| DSL to the createElement function call pattern (see Preact.h
| for example) and all of the benefits you're describing come
| from the framework and runtime.
|
| More concisely: JSX is just an alternate function call syntax
| with some useful applications.
|
| For example at my last company we used JSX to make test data
| factories that had an XML-like look but were using a builder-
| pattern in the element creation that was able to make
| contextual decisions about what was in the final data. Nothing
| to do with React, DOM, or inability to express the same thing
| declaratively without JSX.
| spoonfeeder006 wrote:
| > For example at my last company we used JSX to make test
| data factories
|
| Thats really interesting, can you elaborate more?
|
| For example did you use a specific JSX compiler? Was that
| written in house or used a 3rd party library?
| LAC-Tech wrote:
| _Returning actual DOM nodes entirely blunts the big advantage
| of JSX (and non-JSX libraries like Lit) - which is their
| immediate mode style API, and UI=f(state) model._
|
| I feel like this is one of the leakiest abstractions in all of
| computing. There's a reason there's an entire cottage industry
| around react; how to stop things rendering multiple times,
| refreshing needlessly, etc.
| littlestymaar wrote:
| Yeah, as much as I liked the idea of an "immediate mode API
| which is in fact retained under the hood which makes things
| both ergonomic and performant", the reality is that React
| failed to deliver on that and every sufficiently big app ends
| up having performance problems that are then fixed by opting
| out of the immediate mode illusion.
| austin-cheney wrote:
| Whether you like this project or not, your comment so
| completely misses the point. You are confusing the JSX syntax,
| which is what the author wanted by extracting it away from
| React, for all the React candy. This is a missing the forest
| for the trees kind of thing.
|
| This mind numbing reliance upon layers of abstraction nonsense
| around state management is why I really don't like React. State
| management is ridiculously simple. State management, when done
| correctly, is the most primitive example of MVC with no
| abstractions needed.
| SkiFire13 wrote:
| State management is not simple. You have to constantly keep
| in sync two different piece of states (your data model and
| the UI). Making sure that when you modify some parts of your
| model then everything depending on that is also updated is
| one of the hardest things to guarantee. Fundamentally this is
| because it is non-local: you cannot tell what will change by
| just looking at the definition of what you're mutating.
|
| You might be able to handle this while you're alone and you
| know everything about your codebase, but the moment you're
| working with someone else or in a team this will no longer be
| the case.
| novocantico wrote:
| > is probably the main benefit of a VDOM
|
| I get the "no more imperative updates" dream. I've used these
| frameworks for probably a decade. I've mastered them.
|
| Me personally, I prefer imperatively updating my DOM. I get
| completely fine-grained control over what's happening. I can
| architect it to be an extremely efficient machine. I can make
| it extremely easy to add/change/remove/fix features in my apps
| without forcing myself to think according to anyone else's
| opinionated methodology.
| nine_k wrote:
| If you have little state, or simple uniform state, you can
| actually store it in the real DOM efficiently, as values of
| controls, or lists of similar DOM nodes under a common known
| parent. If most of your DOM is static, and you only need
| small bits of interactivity, React is an excessively heavy
| tool.
|
| The farther you get into complex GUI territory, the more you
| want a declarative, functional approach, because it makes
| things simpler. The closer you are to a handful of controls
| with simple logic, the more you want to just imperatively
| tell them what to do, and leave the rest of the page alone,
| because it makes things simpler. We now just have better
| tools than jQuery for that.
| newzisforsukas wrote:
| there is no reason something imperative cannot be
| declarative. the war is one of style, not capability, so
| saying you gain "fine-grained control" is kind of
| meaningless, imo
| francasso wrote:
| From my experience creating complex web UIs, the performance
| angle of using a vdom is pure fantasy if your application is
| complex enough.
|
| In fact I now strongly believe it's counter productive, because
| most people come to it thinking "I can just trigger however
| many re-renders of this large piece of UI as I like, the vdom
| makes it ok" and it doesn't, the performance sucks, but now you
| have architected the app in a way that requires a rewrite to
| make the app perform well.
|
| I have seen this exact sequence of events four times, by four
| different teams. The second, third and fourth, as a principal
| architect consulting for the team I tried to intervene and
| advocate for a vanilla architecture that is mindful about
| performance, citing the issues they would likely experience
| with react, but to no avail. There was a lot of "oh but there
| many ways to avoid those issues" followed by a list of things I
| was presumably ignorant about.
|
| I guess most of us need to learn things the hard way.
| kristiandupont wrote:
| And from _my_ experience building complex web UIs, those team
| members were right -- there are many ways to avoid the issues
| and using vdom is great in general. True, there are
| situations where it falls short, which is why you will want
| to fall back to other techniques for those bits of
| architecture. Just like your JS, Python or Ruby server will
| call a bunch of functions written in C or the like. That
| doesn 't mean you should write your entire backend in C.
| littlestymaar wrote:
| Yes, there are ways to avoid the issues, and they involve
| abandoning the immediate mode illusion that react created
| in the name of simplicity.
| johnfn wrote:
| Write it in React, and if you run into performance
| issues, there are a bunch of well-known performance
| optimizations you can make which are easy to discover.
| It's a well-trodden path that many engineers have walked
| before.
|
| Write it in your own vanilla framework, and you will
| effectively re-invent all the complexity of React, but in
| a way that no one has ever done before. It's easy at
| small application scales, but once your app gets large,
| good luck debugging the thing that exists primarily in
| your principal engineer's head.
| unconed wrote:
| Yes and the solution is to put on your big boy pants and to
| actually do your front-end application architecture properly.
|
| Separate source of truth from derived data. Separate possibly
| valid user intent from validated state. Use contexts to
| organize the data dependency graph of your application.
| Ensure all your widgets use a consistent value type in and
| out, don't let events contaminate it. Use something like
| cursors or optics to simplify mutations and derive setters
| automatically.
|
| I've never had an easier time building very complex UI
| functionality than with React. But it requires you to
| actively start reasoning about change in your code (what
| doesn't change), and this is something most people are not
| used to.
|
| Personally I think React compiler is folly for this reason:
| they are taking the most interesting part of React, the part
| that lets you write apps that are incremental from top to
| bottom, and telling you it's too complicated for you to think
| about. Nonsense.
|
| The issue is just that React makes pros feel like idiots
| unless they eat some humble pie and grok the principles and
| the reasons behind it. Which is that React is what you get
| when you try to come up with a UI architecture that can make
| entire classes of problems go away.
|
| Without a VDOM, one way data flow, and diffing, your UI won't
| just be slow, it'll be full of secret O(n^2) cascades, random
| ifs to stop infinite cycles, random "let's update this state
| early so other code can immediately use it" ordering issues,
| and so on.
| kitkat_new wrote:
| > I've never had an easier time building very complex UI
| functionality than with React.
|
| How many frameworks did you have experience with?
|
| > Without a VDOM, one way data flow, and diffing
|
| you wanted to write "or" not "and", didn't you?
| darepublic wrote:
| > Without a VDOM, one way data flow, and diffing, your UI
| won't just be slow, it'll be full of secret O(n^2)
| cascades, random ifs to stop infinite cycles, random "let's
| update this state early so other code can immediately use
| it" ordering issues, and so on.
|
| you can adhere to the same principles (one way data flow)
| without vdom. Not saying it's easy at large scale but it's
| possible. I don't appreciate people invoking fud towards
| anyone opting out of their tech choice.
| kitkat_new wrote:
| you shouldn't project from react to vdom in general:
|
| https://dioxuslabs.com/blog/templates-diffing
| novocantico wrote:
| There were two groups I was hoping vanillajsx would resonate
| with. The first is people who still buy into the React dream
| but are beginning to be disillusioned with its inability to
| deliver on its promises, and the second is people who already
| are fully disillusioned.
|
| Specifically, I'm hoping to show that vanilla architectures
| can be not only performant, but easy to maintain with well
| designed code that uses stable and known patterns. Using JSX
| just so happens to clean up the code nicely and make the
| relationship between React and vanilla very visible, but
| that's really all it did here.
|
| Although to be fair, the hack required to get JSX-as-DOM to
| work is really unfortunately and I'm not very happy with it,
| and I would prefer JSX to just render as an object tree that
| anyone can render however they want. But when I tried that
| for a few months or a year, it was not nearly as performant
| as rendering them as strings as soon as they're evaluated,
| which can then be cached via standard module caching. At
| least, that's how I got immaculatalibrary to entirely render
| all HTML files in ~700ms initially and ~70ms on most file
| changes.
|
| I'll try to do some experimentation next week to see if I can
| get more performance back out of having <foo
| bar={qux}>child</foo> to render as {foo:{bar:qux,
| children:[child]}} again though, because that would
| absolutely be the ideal, and would unfork JSX in the same way
| Typed Annotations proposes to unfork JavaScript types.
| Joeri wrote:
| Thank you for posting this! VanillaJSX is refreshingly
| different, and we desperately need new ideas in the front-
| end space to reduce the complexity and get closer to the
| browser. I also feel like the discussion in this thread is
| very rich and gives people on both sides of the fence a lot
| of stuff to think about.
|
| _There were two groups I was hoping vanillajsx would
| resonate with. The first is people who still buy into the
| React dream but are beginning to be disillusioned with its
| inability to deliver on its promises, and the second is
| people who already are fully disillusioned._
|
| I don't know if you've seen it, but Alex Russell just did a
| blog series where he directly talks about this disillusion
| and proposes a move away from React for most web apps:
| https://infrequently.org/series/reckoning/
|
| I am not as anti-React as that myself, but I do agree it is
| hard to scale up and have it perform well, not at all like
| the promise. As always, there are no silver bullets and you
| have to pick a stack that you can understand.
|
| By the way, I made my own pitch for fully vanilla web
| development here: https://plainvanillaweb.com/
| merrywhether wrote:
| IMO that blog series misses the point. Knowledgeable
| motivated developers can make great experiences with any
| technology, and conversely there are bad experiences
| built with every technology. That series blames the
| people involved for not being better, but that's just
| blaming plane crashes on human error and calling it a
| day.
|
| - If the UK GSD is anything like USDS, using them for
| comparison is like comparing a pro sports team to your
| local high school's. They are an outlier specifically
| created to be better than the average, so tautologically
| their stuff will be better. Code For America is a
| similarly odd comparison.
|
| - The US has a massive gap in pay and prestige between
| public and private sector developer jobs. It's not that
| this means "worse" people work at public jobs, but in
| general they start less experienced and can wind up in a
| non-learning cycle as they don't get mentorship/guidance
| from more expert folks, and if they do get good
| independently they leave. It's really hard to convince
| people to take a pay cut to work these jobs, and many of
| the few willing to do so instead go to CFA, USDS, etc
| because they want prestige and avoid all the other
| inefficiencies in public jobs.
|
| I could go on about the structural problems leading to
| this, but suffice it to say that blaming React and other
| JS frameworks is a miss. For some services it's lucky
| they are online at all, and a slow web page is still
| orders of magnitude faster than physical mail or god
| forbid going to a physical office. The sites could
| definitely be better but this is not fundamentally a
| problem of technology choice.
| no_wizard wrote:
| You might find this project[0] interesting if you haven't
| given it a look.
|
| It was attempting to do something along the same lines as
| you first suggest
|
| [0]: https://github.com/jridgewell/jsx2
| k__ wrote:
| Wasn't the issue mostly solved with signals?
|
| As far as I understand, signals make it much easier to keep
| the DOM updates to a minimum.
| resonious wrote:
| It sounds to me like GP got told stuff exactly like this,
| with the team eventually not actually doing the thing.
| darepublic wrote:
| More than once I got asked on interviews why react is faster
| than vanilla JS and I had to tell them no, it isn't.
| jameshart wrote:
| The clue would be in the fact that react is _running in
| vanilla JS_.
|
| There is a persistent 'learned helplessness' tendency among
| some developers to assume that the frameworks they are
| using have access to magical mystical powers above and
| beyond those that their own code can make use of.
|
| Framework code might well be better optimized or more tuned
| than the code you would write - but if you cared to employ
| similar techniques you could achieve those same gains; on
| the other hand, since by definition it's more flexible than
| single-purpose code, it might not be optimal for your
| usecase.
| johnfn wrote:
| The "performance angle" isn't really an angle. It gets
| bandied around by junior devs new to React, but it's not the
| primary selling point of React - in fact, it's not a selling
| point at all. Don't believe me? Just go to http://react.dev
| and look - no where on the site does it say that React is a
| hyper-performant library. It's not! If you need blazing
| performance, you're best off using something much more
| minimal, or even vanilla JS.
|
| When people say that React is fast, what they mean is that
| React can dom-diff faster than a naive O(n) approach. It
| means that updating a component with a thousand nested divs
| won't crash out your browser, like it might if you were to
| write the code by hand. It doesn't mean it's an objectively
| high-performing framework.
|
| What React _is_ good at is forcing you to write code in a
| clear, comprehensible way. Having every engineer on your team
| obey F(props) = state is a strict improvement over virtually
| any other paradigm. (Yes, you can still make a tangle of
| components if you try hard enough, but the complexity of the
| tangle is capped significantly lower than the complexity of a
| tangle of JS without any framework attached.)
| dminik wrote:
| This really just isn't true. If your state updates are at the
| component subtree level (like react) a vdom is a good choice.
| But, if you make your state changes more granular, you can get
| away with skipping VDOM entirely and work with just* regular
| dom nodes. Look at Solid or Svelte. No VDOM there, just pure
| granular updates.
|
| *List reconciliation still has to happen, but you don't need to
| pull out an entire vdom. You just have to have some mapping
| between list items and their resulting DOM nodes.
| SkiFire13 wrote:
| TBF while Solid and Svelte don't use a VDOM on which they
| perform diffing, they still ultimately create a tree parallel
| to the DOM which is used to track dependencies.
| AltruisticGapHN wrote:
| I'm having fun using lit-html with vanillajs, after I saw a
| tweet from Marc Grabanski suggesting he didn't use the full Lit
| library. Admittedly I am then not taking advantage of all the
| reactivity goodness, but I also really dislike the decorators
| syntax and 95% of the time I just don't need the reactivity
| after the first render.
|
| It works great! I was amazed at how you can do so much in
| templates, it's pretty much everything I could do in Vue
| templates, though a little more verbose.
|
| I built my own `VanillaComponent` class, which has a mount()
| method which calls the render() function which I define on the
| child class.
|
| My VanillaComponent class looks like this:
| import { html, render } from "lit-html";
| abstract class VanillaComponent { abstract render():
| ReturnType<typeof html>; private
| _mountPoint?: HTMLElement; mount(this:
| VanillaComponent, target: HTMLElement) {
| target.textContent = ''; this._mountPoint = target;
| this._update(); } _update() {
| let templateResult = this.render(); let rootPart =
| render(templateResult, this._mountPoint!); }
| }
|
| So I can write something like class
| MyComponent extends VanillaComponent {
| constructor(props: { label: string }) { this._props
| = props; } render() {
| return html`<button>${this._props.foo}</button>`; }
| }
|
| Then I can instance like so: let myComponent
| = new MyComponent({ label: "I am a button" }); let
| target = document.querySelector("#demo");
| myComponent.mount(target);
|
| The base class stores the root node (target), so later I can do
| myComponent.update()
|
| to re-render, taking advantage of lit-html's "diffing" logic.
|
| However something I have not been able to solve with lit-html
| only, is when I compose parent and child components I have to
| do something like : class MyDialog extends
| VanillaComponent { render() { let
| childComponent ... // another VanillaComponent previously
| instanced return html` <div>
| ${childComponent.render()} </div>
|
| So the child component I need to explicitly call render() to
| get the TemplateResult for the parent template.
|
| But this means I can not do `childComponent.update()` because I
| don't know the root element of child component, since I did not
| mount it explicitly myself.
|
| I mean technically because of the lit-html optimizations, I can
| do `.update()` on myDialog (the parent component) after any
| child component's props changes, and it will only re-render
| what is necessary... but let's say my child component has like
| 1000 cards... it seems very wasteful and it would be ideal if I
| could re-render only the child.
|
| I wonder if there is a trick to get around that with just lit-
| html?
| mst wrote:
| It's always worth checking the lit built in directives list
| for the one you've still missed (or at least it is for me ;).
|
| I think in this case the ref() directive - i.e.
| https://lit.dev/docs/templates/directives/#ref - may be what
| you want. If it isn't exactly, reading how it's implemented
| would be my first step towards building something similar
| that is.
| croes wrote:
| Svelte and SolidJs work pretty well without VDOM
| kolme wrote:
| Nice, I love lit-html(1)!
|
| I wanted to add my two pennies to the discussion. You are of
| correct that with that approach you lose the declarativeness
| but sometimes you don't need that, if the thing is mostly
| static.
|
| I went this road many years ago for a project. The nice thing
| of this approach is getting rid of all the ugly DOM API but
| enjoying it's performance over innerHTML.
|
| (1) I absolutely love lit-html but don't like the rest of the
| lit components framework. Luckily you can use it independently!
| skrebbel wrote:
| JSX in SolidJS directly returns DOM elements much like in the
| top part of this post, yet it does not have these
| disadvantages. It's true that strictly put it's not immediate
| mode like React and Lit are, but the framework is designed such
| that there's few practical downsides to that.
| PKop wrote:
| UI is not a pure function of state[0], "UI state" is relatively
| stable and does not have to be recreated constantly when data
| input changes.
|
| [0] https://blog.metaobject.com/2018/12/uis-are-not-pure-
| functio...
|
| >you want to be able to reevaluate your templates repeatedly
| with new state
|
| No you don't. It is inefficient and increases complexity. You
| then have to extract and keep track of state yourself where the
| platform/UI components could have done much of this themselves.
| Calling the same method over and over again is wasteful.
| So we don't do that. First, we did not start with
| the obviously incorrect premise that the UI is a simple "pure"
| function of the model. Except for games, UIs are actually very
| stable, more stable than the model. You have chrome, viewers,
| tools etc. What is a (somewhat) pure mapping from the model is
| the data that is displayed in the UI, but not the entire UI.
| So if we don't make the incorrect assumption that UIs are
| unstable (pure functions of model), then we don't have to
| expend additional and fragile effort to re-create that
| necessary stability.
| lucideer wrote:
| If the above is what you need there's not strong reasons not to
| use React or similar. But for most things that will lead to an
| interest in "Vanilla JSX" this line of thinking is premature
| optimization - the advantages of vdom are extant but enormously
| overstated. JSX has many other advantages.
|
| It's also not even an either-or. I've worked on a codebase that
| did both: React was loaded for some views & others were served
| with a lightweight JSX renderer.
| recursive wrote:
| I also made a UI library based on the idea of jsx template
| expressions that produce real DOM nodes. It also binds model
| objects to attributes, eliminating some of the imperative event
| handler boiler-plate. I think it's a great idea, but of course I
| would.
|
| https://github.com/tomtheisen/mutraction
|
| It lets you do stuff like this. const model =
| track({ clicks: 0}); const app = ( <button
| onclick={() => ++model.clicks }> { model.clicks }
| clicks </button> );
| document.body.append(app);
| cyanydeez wrote:
| I just don't understand how people can configure their brains to
| parse html inside JavaScript
| zazaulola wrote:
| You're not alone. Someone suggested that the W3C should convene
| a Community Group to discuss JSX, but the grown guys involved
| in writing standards immediately scrapped the idea.
| 1attice wrote:
| There's a trick to it. Kind of like one of those 'magic eye'
| stereograms that were popular in the nineties. You sort of
| unfocus and boom, there it is.
|
| It also reminds me of that Douglas Adams line about flying:
| it's the trick of falling and completely missing the ground, so
| in order to do it, you can't think about it too hard.
| xigoi wrote:
| If there can be JS inside HTML, why not HTML inside JS?
| flowerlad wrote:
| This is very similar to Vanilla TSX:
| https://github.com/wisercoder/uibuilder
|
| Here's an app written using Vanilla TSX:
| https://github.com/wisercoder/eureka/tree/master/webapp/Clie...
| andrewstuart wrote:
| Just out of interest I wanted to see something a little bit
| similar in Web Components: <html lang="en">
| <body> <h1>Web Components Examples</h1>
| <h2>Counter Component</h2> <counter-
| component></counter-component> <h2>Clickable Button
| Component</h2> <clickable-button></clickable-button>
| <h2>Toggler Component</h2> <toggler-
| component></toggler-component> <script>
| class CounterComponent extends HTMLElement {
| constructor() { super();
| this.count = 0; this.button =
| document.createElement('button');
| this.button.textContent = this.count;
| this.button.addEventListener('click', () => {
| this.count++; this.button.textContent =
| this.count; });
| this.attachShadow({ mode: 'open' }).appendChild(this.button);
| } } class ClickableButton
| extends HTMLElement { constructor() {
| super(); this.clicked = false;
| this.button = document.createElement('button');
| this.button.textContent = "Click me!";
| this.button.addEventListener('click', () => {
| this.clicked = !this.clicked;
| this.button.textContent = this.clicked ? "Clicked!" : "Click
| me!"; }); this.attachShadow({
| mode: 'open' }).appendChild(this.button); }
| } class TogglerComponent extends HTMLElement
| { constructor() { super();
| this.on = false; this.button =
| document.createElement('button');
| this.button.textContent = "OFF";
| this.button.addEventListener('click', () => {
| this.on = !this.on; this.button.textContent =
| this.on ? "ON" : "OFF"; });
| this.attachShadow({ mode: 'open' }).appendChild(this.button);
| } } customElements.define('counter-
| component', CounterComponent);
| customElements.define('clickable-button', ClickableButton);
| customElements.define('toggler-component', TogglerComponent);
| </script> </body> </html>
| slmjkdbtl wrote:
| I never understand the appeal of JSX over something like
| h("div", {}, [ h("p", {}, "this is easy"),
| ...list.map((l) => h("li", {}, l), ])
|
| With this you automatically get loops, variable interpolation etc
| without having to invent a compiler and new syntax. Can someone
| help me understand?
| fredmerc wrote:
| Keep going down that logical rabbit hole. You end up with
| Common Lisp!
| erikpukinskis wrote:
| You might be confusing JSX for something else. In JSX you also
| don't need new syntax for loops. JSX Is JavaScript, as people
| like to say.
|
| But to your point, JSX doesn't really do much. Your h function
| is basically what React.creatElement does. Google "React
| without JSX" and you'll see how it looks.
|
| JSX is just syntactic sugar over React.creatElement. And that
| is what makes it so nice... there _are_ no special constructs
| for loops, or variables, or components. They are actual
| JavaScript loops, JavaScript variables, and JavaScript
| function.
|
| It makes JSX easier to reason about than most templating
| languages.
| sim0n wrote:
| I would assume that lot of people just find the JSX equivalent
| a lot more readable and familiar (a matter of opinion, of
| course.) <div> <p>this is easy</p>
| {list.map((l) => <li>{l}</li>)} </div>
|
| > you automatically get loops, variable interpolation etc
| without having to invent a compiler and new syntax
|
| To be fair to JSX, you use regular loops, interpolation, etc
| without any different syntax (`{}` accepts a vanilla JS
| expression), you just obviously need the compiler step to de-
| sugar the element tags to `createElement` calls.
| slmjkdbtl wrote:
| Yeah the syntax is almost identical to vanilla js, but
| requiring a compiler is quite cumbersome compared to the
| advantage it provides imo.
| presentation wrote:
| That said if anything pretty much all of the new school
| frameworks and many of the tools in their ecosystems are
| already dependent on compilers for optimization anyway,
| react itself is introducing a compiler in the latest
| versions.
|
| Anyway I prefer the html looking syntax if anything because
| it looks like the output on the page. That's dependent on a
| project coding style that doesn't unnecessarily wrap things
| in components, which for my company's product I've set as a
| standard.
| littlestymaar wrote:
| Requiring a compiler also allows to catch mistakes at
| compile type, which is much more efficient in terms of
| development.
| plonq wrote:
| I've wondered the same thing. I think one benefit is that it
| looks like HTML, which means it looks similar to what you see
| in the browser's DevTools, which makes it easier to compare and
| debug.
| usrusr wrote:
| It also makes it easier to see what it's _not_ : at a glance,
| the "p" could really be anything until you scan the context.
| The <p> isn't a string (that on further examination turns out
| to get used for marking up a paragraph), it _is_ a paragraph
| demarkation (in vdom, but still).
| whichdan wrote:
| Elm works a lot like this and it's quite nice.
| dimal wrote:
| Here's my perspective. I never understand how some people could
| look at the code you pasted and think that's just as good. But
| different people's brains process information differently. Your
| example has a lot of punctuation that's very difficult for me
| to parse quickly. I don't see the DOM structure that's being
| created unless I manually pick the syntax apart in my mind, but
| understanding the DOM structure at a glance is far more
| important to me than whether I need a compiler. For the record,
| I'm neurodivergent. I hope that helps.
| slmjkdbtl wrote:
| Yes I can understand it helps if it looks like DOM on first
| sight, I'm thinking more about the functional aspect where it
| can achieve the same thing without requiring a compiler and a
| new syntax (altho you can argue it's not new syntax just js +
| html)
| dimal wrote:
| It doesn't achieve the same thing, though. Functionally,
| for the computer, it's the same. But code has two
| audiences: the computer and the coder who has to read and
| write it. And from my perspective, the human is more
| important than the computer. And JSX is more than a
| convenience at first glance. You read a lot more code than
| you write. If all of my code was written like this, it
| would add significant cognitive load, make the code more
| difficult to reason about and slow me down.
| 65 wrote:
| Because that code is very hard to read, especially with a
| complex HTML structure.
| codingdave wrote:
| For a single file or simple app, sure, your style works fine.
| But when you get a few hundred components in a complex app,
| importing them into each other and writing them as JSX tags
| feels like a simple, easy to understand syntax, as least to me.
|
| And that is what a lot of the pushback against React seems to
| come down to as well -- it is overkill for simple things. And
| it is. But different people doing different apps with different
| levels of complexity... all have different needs.
|
| So it is not as simple as one having appeal over the other.
| They are different tools for different problems.
| girvo wrote:
| Does the final example not work in Firefox for anyone else? It
| worked in Edge, but not Firefox for me Uncaught
| (in promise) TypeError: Map.groupBy(...).entries().map is not a
| function
| iammrpayments wrote:
| Object.groupBy doesn't seem to be available to all browsers
| before march 2024: https://developer.mozilla.org/en-
| US/docs/Web/JavaScript/Refe...
| ilrwbwrkhv wrote:
| Imba is what anyone interested in this sort of thing should look
| at. I have no idea why it is not more popular. Maybe because JS
| devs falls for Faang marketing easily.
|
| https://imba.io/
| xigoi wrote:
| Many programmers seem to be scared of anything that doesn't
| have semicolons and braces.
| EugeneOZ wrote:
| As often happens with minimalistic approaches, it only looks
| interesting on very small and very simple examples.
|
| After "How would they handle large data?" it turns into an
| unreadable mess.
|
| Communication between elements is not covered, global deps, DOM
| updates scheduling, content projection, and so on - you "just
| don't need it" in small demo examples, but you do need it in the
| real apps.
| frabjoused wrote:
| It's already solved. It works well. Just walk away.
| hizanberg wrote:
| Anyone else used Hono with SSR JSX? [1]
|
| Was super productive and easy to create a Cloudflare Worker Web
| App that's free to host thanks to Cloudflare's generous 100k
| daily worker request limit.
|
| Generally don't believe in serverless for larger Apps, but for
| small websites that you just want to create, deploy and ignore -
| it's great!
|
| https://hono.dev/docs/guides/jsx
| drikerf wrote:
| Nice project! I do wonder though if jsx is the best way to
| represent elements in code?
|
| Clojure datastructures makes this so much more enjoyable.
| Everything is just basic lists and maps which makes it very
| flexible and powerful.
|
| [:ul [:li "task 1"] [:li "task 2"]]
|
| It's weird that it's not more common for making web apps.
| globular-toast wrote:
| There is a library for Python called htpy that does this.
|
| Trouble is if you're used to HTML it can take a while to get
| used to it. It's like a learned helplessness or something.
| edflsafoiewq wrote:
| There are a lot of DOM util libraries that look like
| h("ul", h("li", "task 1"), h("li", "task 2"))
|
| This is called "hyperscript-style" after an early library that
| used it. This is basically what JSX compiles to too. There used
| to be a lot of JSX vs hyperscript debates.
|
| There's also variants like h.ul(h.li("task 1"), h.li("task 2"))
| using Proxies now too.
| mg wrote:
| What is the benefit of mixing js and html? el =
| <button>Click me</button> as HTMLButtonElement;
|
| What would be the downside of el =
| html.button('<button>Click me</button>');
|
| ?
|
| That way no compilation step would be needed and debugging would
| be easier as the code executed in the browser is the same code
| the developer writes.
| littlestymaar wrote:
| With the first example you have syntax highlighting and
| compile-time check.
|
| With the second of you have stringa.
| mg wrote:
| Why wouldn't one be able to tell syntax highlighters and code
| checkers that the string that goes into the html.something()
| functions is html?
| Joeri wrote:
| If you use a html`` tagged template literal combined with the
| html-in-template-string vs code extension you get syntax
| highlighting. A simple html identity literal function is a
| one-liner: https://developer.mozilla.org/en-
| US/docs/Web/JavaScript/Refe...
| moffkalast wrote:
| The benefit is that it makes people puke from looking at it so
| you have more job security I guess. Putting xml onto the same
| line with a scripting language is like mixing toothpaste and
| orange juice.
|
| I don't understand why people take such offense to calling
| document.createElement() or document.getElementById() or kind
| of document. or window. function. It's consistent and native.
| whazor wrote:
| I don't see why the type casting (as HTMLButtonElement) is
| needed. Because document.createElement("button") returns
| HTMLButtonElement in TypeScript.
| miika wrote:
| I used to explore similar stuff and prototyped something I call
| "Vanilla Components" but then in the end I fell in love with Web
| Components and quit React (and all other frameworks).
| merlindru wrote:
| VanJS deserves a mention here! https://vanjs.org/
|
| Another interesting thing is that other JSX libraries like
| Solid.JS also return DOM nodes, and I love that this idea is
| gaining traction
|
| The closer we get to the platform we're using, the better. Being
| removed by layers of abstractions CAN be useful, but in practice,
| I haven't found a use for abstracting away the platform. (yet.)
|
| Maybe huge projects like Facebook benefit from this tho (which I
| haven't worked on)
| croes wrote:
| Isn't SolidJS useless in the bundle size comparison?
| novocantico wrote:
| That may be a point in favor of imlib.
|
| Technically this is the only code bundled with vanilla jsx:
|
| https://vanillajsx.com/@imlib/jsx-browser.js
| dqh wrote:
| Those interested in this space may find my fairly unknown project
| interesting: https://nakedjsx.org/
|
| It started as a static site generator but added a bunch of
| support for client JavaScript too.
| n3storm wrote:
| For me is like old PHP where HTML and controlling and data access
| was all around. We use to call it spaghetti code.
| NaN1352 wrote:
| How does this stack up aginst using lit-html?
| NaN1352 wrote:
| I'm having fun using vanilla js with lit-html. Using string
| templates instead of jsx. VSCode extensions for lit make it
| almost identical to editing vue templates with type checking etc
| cies wrote:
| I frown at JSX. Just a layer of abstraction that is so "leaky"
| that you have to know what actually goes on in the layers below
| or you are fucked.
|
| It looks simpler at first glance/ to a untrained eye; but it's
| just adding complexity without really solving any problems.
|
| I like approaches like Kotlinx.html, scalatags, Elm's HTML
| package or HtmlFlow. They are also abstractions, but they add
| typesafety that html-as-a-string does not offer. On top of that
| you get breakpoints, code completion, and you can keep working in
| one language.
| talkingtab wrote:
| A side question. The advantage of JSX I see is the ability to
| connect, declaratively, components. I find this very helpful in
| terms of understanding programs I write. I wonder if I use React
| not because of the virtual dom, but simply because of JSX.
|
| So I would like to explore the ability to use JSX in non-DOM
| environments. react-three-fiber does this with Threejs, but then
| it is still React oriented. I found this article about parsing
| JSX https://blog.bitsrc.io/demystifying-jsx-building-your-own-
| js.... And I know babel has something that parses JSX.
|
| Does anyone have recommendations for doing this. Threejs to me a
| good candidate - a non React version, since it is a hierarchical
| system (scene, meshes, materials etc), but I suspect there are
| other applications.
|
| I made an attempt to implement a Javascript version of Hickey's
| transducers - a sort of conveyor belt of functions and that is
| another instance of a series of processing steps that might be
| best represented in JSX
| erikpukinskis wrote:
| I see what you're getting at, but technically the virtual DOM
| is what makes JSX declarative.
|
| JSX doesn't actually write anything, it's just a templating
| language over React.createElement.
|
| It's the virtual DOM that actually syncs those structures
| created by createElement to the real DOM. So it's the virtual
| DOM that allows you to write your code declaratively.
|
| That's evidenced by OP's project, which is JSX without the
| declarative piece. You just get an Element and then you have to
| update it imperatively if you want to change anything.
| andruc wrote:
| It's very strange that when I land on the page for the very first
| time, I land halfway down the page and I'm staring at a block of
| random code.
|
| Not what you'd expect to see.
| andruc wrote:
| #real-todolist has an autofocus element and I'm using Firefox
| novocantico wrote:
| Oops. Fixing now.
| andruc wrote:
| \o/
| andruc wrote:
| Any comparisons on performance?
| emadda wrote:
| One of the reasons for JSX originally was to reduce usage of the
| DOM APIs, as they are slower than direct JS object manipulation.
| The JSX diff of prev/next allows you to minimize DOM API calls.
|
| I would guess there is more overhead in creating a dom element
| than a JS object (which JSX elements compile to).
| austin-cheney wrote:
| React came out in 2013. At that time object manipulation would
| likely have been, at best, only marginally faster than writing
| to the DOM.
|
| First, you have to understand that at that time Firefox was
| about 500x faster at accessing the DOM than Chrome and about
| 250,000x faster accessing the DOM via the API methods than via
| querySelectors. Firefox and Chrome performed about equally in
| use of querySelectors with Chrome being a tiny bit faster. So,
| the DOM was already fast, but occupied a different memory space
| than JS.
|
| At any rate the original motivation had nothing to do with
| performance. The goal was to introduce a template system that
| fit with React's state/component system. JS modules weren't a
| thing yet, so code organization was very different at that time
| and centered around concepts like AMD and Common.js, though it
| was mostly some form of AMD typically require.js.
|
| The design of the template system in Vue was created to solve
| for the exact same conditions according to the internal
| organization of Vue.
| emadda wrote:
| Respectfully, my experience says otherwise:
|
| https://jsben.ch/cSWJa
|
| - JS object appears to be at least 2x faster than
| document.createElement() (Chrome)
|
| - Note: JS object only loosely represents JSX element so it
| is a bit unfair. But with actual JSX objects I would assume
| it is still somewhat faster than the DOM API.
|
| https://youtu.be/DgVS-zXgMTk&t=1532
|
| - Pete Hunt, one of the React devs, says "JSX is faster than
| the DOM because it is JS memory."
| NohatCoder wrote:
| For anyone who can live without <> syntax I made DOM Maker, no
| compilation step, no injection vulnerability footguns, just make
| a bunch of function calls in a tree structure, and you get DOM
| with the same tree structure, complete with non-string event
| handlers.
|
| Mostly I just do Vanilla.js, but the vanilla DOM creation
| functions turn really verbose, I got tired of that and created
| this to cut back on code size and increase readability.
|
| There are other libraries that do something similar, but in my
| own very biased opinion this is one of the better.
|
| https://github.com/NoHatCoder/DOM_Maker
| jwtorres wrote:
| I genuinely don't understand why anyone would be interested in
| using frameworks on top of JS. None of them can do anything that
| pure JS can't do (+libraries), they just make it less readable
| and less intuitive compared to the original C-like syntax of JS.
| JS libraries make sense, of course, but why keep messing with the
| syntax?
| nf17 wrote:
| Great job, is there something similar but for SwiftUI?
| xwall wrote:
| No matter how complex your app is but still React will not break,
| performance on web is not a big issue as benchmarks say, even a
| junior developer can achieve 90%+ lighthouse score, but any
| senior developer may fail to ship it successfully.
|
| ultimately go to react.dev because: "Maturing is realizing React
| is best"
___________________________________________________________________
(page generated 2024-08-17 23:01 UTC)