57 ms·
Virtual DOM is pure overhead (2018)
- ramesh31 4y agoSo is the JS runtime. So why don't we just write apps in raw WASM?
- geraldwhen 4y agoI suspect that in 15 years that or something similar will be a compile target for typescript or similar.
- syncerr 4y agoReact-DOM will probably just compile to WASM.
- traverseda 4y agoSerious answer? SEO and accessibility. HTML lets search engines crawl pages and screen readers read pages (which can often be a legal requirement). If we're rethinking the web stack I'd advocate for htmx with wasm-based web components for more complicated stuff like if you needed to polyfil in some new image format, or run a terminal emulator, or do webrtc calls with your own fancy custom noise reduction algorithm. Yes I realize I'm essentially advocating for jquery with java applets, but it could really work this time! (I think a lot of the issues originally were political) Make htmx like attributes part of the HTML spec, keep working on web components. Still don't know why web components haven't taken off.
- randomdata 4y ago> Serious answer? SEO and accessibility. How is WASM less accessible than Javascript? Are crawlers parsing minified and obfuscated Javascript sources and deriving meaning from them in a way they couldn't from WASM code?
- CharlieDigital 4y agoShort answer: yes. Crawlers are based on consuming text. HTML is text. Sites that optimize for SEO also use JavaScript to provide SEO context. The specific standard is called JSON+LD; pretty much any site that you use where SEO matters has JSON+LD, RDF-a, or Microdata embedded in the HTML. You can see these structures if you use the Schema.org validator: https://validator.schema.org/ https://validator.schema.org/ Try plugging in a URL like Reddit.com and see for yourself. On e-commerce websites, it's a *must have*. For example, try this Amazon page: https://www.amazon.com/dp/B09V3GZD32 https://www.amazon.com/dp/B09V3GZD32. TL;DR: crawlers are parsing RDF-a and Microdata in the HTML or JSON+LD embedded in `<script/>` tags. You can learn more about it here: https://developers.google.com/search/docs/appearance/structured-data/intro-structured-data https://developers.google.com/search/docs/appearance/structu...
- randomdata 4y agoHere's an excerpt of some Javascript found on the Amazon link: window.ue_ihb = (window.ue_ihb || window.ueinit || 0) + 1; if (window.ue_ihb === 1) { var ue_csm = window, ue_hob = +new Date(); (function(d) { var e = d.ue = d.ue || {}, f = Date.now || function() { return +new Date }; e.d = function(b) { return f() - (b ? 0 : d.ue_t0) }; e.stub = function(b, a) { Feel free to visit it to find the entire script. It is much too large to post here. What is a crawler learning from that program that would be lost if the equivalent code was bundled as WASM instead? Why couldn't its WASM parser pull out the same information? The JS/WASM runtime in the browser has to produce the same result regardless of which encoding is chosen, so everything will be encoded in there somehow.
- CharlieDigital 4y ago> Why couldn't its WASM parser pull out the same information There's currently no standard. If there's a will, there's a way. JSON+LD is the standard for JavaScript based metadata.
- amelius 4y agoDo you have benchmarks showing that it is worthwhile? Anyway, another idea is to ditch the entire DOM and render on the canvas.
- scotty79 4y agoThat would mean we need no re-invent all form controls and other gui elements. And it's super hard. Desktop envs are trying to do it for decades and Electron just came and ate their lunch.
- overgard 4y agoThe translation layer of calling a web assembly function from javascript is a bit heavy, at the moment. And you have concerns around modeling a flat memory space with pointers, so it can be greedy on memory use. That said, I wouldn't be surprised if this is where the industry moves 5-10 years
- ramesh31 4y agoI guess the sarcasm was too thick. My point was that yes, VDOM has overhead. But we accept it as a tradeoff for app development in the name of DevX.
- synergy20 4y agoSwitching from vuejs to svelte these days, indeed svelte is much easier to write and understand.
- imbnwa 4y agoWay I remember, the message was that it was too hard for most devs to be careful enough in their Backbone.View.render code to consistently write fast DOM manipulation that scaled. That may not be whats in the cited talk but that's my recall from the various bits of early marketing by Facebook Engineering. So the sell was alievating that burden.
- paales2 4y agoInferno.js uses VDOM https://github.com/infernojs/inferno https://github.com/infernojs/inferno and is faster than Svelte according to these benchmarks https://krausest.github.io/js-framework-benchmark/2023/table_chrome_109.0.5414.87.html https://krausest.github.io/js-framework-benchmark/2023/table.... Sooo, VDOM can improve performance?
- CivBase 4y ago> Sooo, VDOM can improve performance? This article doesn't really argue against that. They say the VDOM is a "means to an end" and is "generally good enough". The thrust of the article seems to be that a virtual DOM isn't a guarantee of performance. Rather it's just one solution that can be pretty fast. Svelte happens to take a different approach which is also pretty fast.
- spankalee 4y agoYou _can_ get vdom to be fast if you hoist static subtrees, memoize, and skip the diff entirely for some operations. Inferno is known for all kinds of these tricks, but you need compilers for that and in the end vdom is just getting in the way.
- fabiospampinato 4y agoThat's an interesting comparison because: - Svelte is actually strangely slow, I mean there's *one* interesting optimization that having a custom compiler/transform allows you do to for free, which is deep cloning nodes in one go rather than creating them one by one each time, and they ain't doing it. Also, I don't have proof of this anymore, but I had tried running my relatively naive framework without the deep cloning trick, and without any custom transform or compiler at all, on that benchmark, and it was _still_ significantly faster than Svelte. Like Svelte is not that fast when you look at it closely, despite what the perception of the average developer might be, or what the marketing might say. - Inferno is fast for real in that benchmark, and it isn't using signals, which is very interesting. I don't know how Inferno works in depth, but looking at the Inferno implementation for that benchmark [0] I see some shenanigans. Like what's that "$HasTextChildren" attribute? Why is my event handler created like that? Like I'm doubtful that the result in the benchmark will actually translate exactly to the real world. - It's interesting also: if the VDOM is pure overhead why is Svelte creating an object for each instance of a component, kinda like React is doing? You don't strictly need to do that, as proof of that Solid doesn't do that (in production builds), because that's pure overhead for real there. [0]: https://github.com/krausest/js-framework-benchmark/blob/638871c00e40185e37f3ea2c575c2c57c498079d/frameworks/keyed/inferno/src/controller.jsx#L9 https://github.com/krausest/js-framework-benchmark/blob/6388...
- agloeregrets 4y agoI always find these a little funny. "[Commonly held thought with some convenient tweaks] is WRONG...so use our stuff!" Even open source projects are guilty of this type of grifting, everyone wants to win, even without money in the game.
- deleted 4y ago[deleted]
- _Algernon_ 4y agoAll abstractions are pure overhead. Let's code everything by hand by flipping bits in memory using a tiny magnetic needle.
- miohtama 4y agoThis is not correct. Zero cost abstractions are not overhead. Some abstractions are zero cost abstractions. Thus, not all abstractions are pure overhead. More on zero cost abstractions here: https://stackoverflow.com/a/69178445/315168 https://stackoverflow.com/a/69178445/315168
- mixedCase 4y ago> Thus, all abstractions are not pure overhead Sorry for the pedantry, but I believe this would still be wrong as phrased. Maybe "not all abstractions are pure overhead" would work?
- asveikau 4y agoThe Stroustrup quote in that thread is better than what you linked to. The concept was popularized by C++ templates. The idea is that the templated code would be just as good as if you hand wrote it without generics. There's no extra function pointers or virtual calls, extra indirection by pointing to some user data, etc.; the tree node or whatever and data struct are declared as a single entity, there's no runtime callbacks, etc.
- _Algernon_ 4y agoI thought the second half would make it clear that I'm being sarcastic but clearly I'm wrong. Pendants gonna pedant I guess.
- acdha 4y agoThis is over-simplified: the overhead of an abstraction can be cancelled out by work or optimizations which you wouldn't have done without the abstraction. As a simple example, most Python programs are faster than the C code the same developer would have written in the same time because they have a rich library of optimized code and getting it working quickly means that they had more time to focus on algorithm-level improvements. That of course doesn't mean that a C programmer can't beat it in performance but once you're past very simple examples those abstractions are harder to beat than they might seem — I've seen multiple cases where someone thought they could do that and wasted days (or in one case, months) only to eke out less than a 10% improvement. In this case, React is slow and memory hungry because when you make a change you go through this process: 1. Update some value 2. … triggering updates to the virtual DOM 3. … requiring it to caluclate the difference between the real DOM and the virtual DOM 4. … and finally apply the changes to the real DOM That abstraction requires substantial extra state to be stored and managed. If you have a different abstraction which directly manages the DOM, you can avoid steps 2 and 3. The big question is a) does your code do enough manipulation for this to be noticeable? (React is less slow than it used to be but I've seen 4 order of magnitude deltas in optimized React code so it's not uncommon to see it chug with large pages, especially on older hardware like a lot of the public uses) and b) does that other abstraction have drawbacks for your developers which cost you more than the performance savings?
- maxfurman 4y agoI like the looks of Svelte, but this argument is a bit strong. The supposed benefit of virtual DOM being: X application-level virtual DOM changes -> differ detects only Y < X real DOM changes -> Y final DOM operations is faster than X application-level virtual DOM changes -> no virtual DOM diffing -> X DOM operations this depends a lot of how fast the diffing is and how fast the DOM is but unless DOM operations are instant now (and with CSS, layout reflow, etc. I'm not sure how they could be) then there must remain some situations where VDOM has a perf advantage.
- spankalee 4y agoNone of the good frameworks really do any more DOM operations than any other. It's all about how you find out which set of DOM operations need to be done. Svelte does this with a compiler, Lit does it with tagged template literals, and a bunch do it with vdom. Calculating the vdom diff is pure overhead in that if you have better syntax (or a compiler) you can just skip it.
- somethingreen 4y agoThey don't because since React set the bar, any new framework that didn't solve the problem VDOM did in some way, was dead on arrival. If Svelte way is better at minimizing and batching DOM updates, they should probably argue and show that, not misrepresent what VDOM does (while blaming strawmanning on others no less).
- hbrn 4y ago> any new framework that didn't solve the problem VDOM did in some way, was dead on arrival. Most frameworks before and after React were solving that problem one way or another. The reason React won was that V = f(S) turned out to be most user-friendly solution. VDOM is exactly what Rich is saying: a means to efficiently implement V = f(S) Vue/MobX are another, better iteration on the same idea. Svelte, arguably, is even better iteration.
- acdha 4y agoThe browser renders the DOM, so everything pays the cost of updating it. In modern browsers that's really, really, really fast compared to IE6 (the baseline when React was designed), so there are basically two things which make one tool slower than another: 1. Are you updating nodes unnecessarily, especially in ways which force the browser to do more work (see next point)? In general, a tool which does only does the necessary updates is going to win. 2. Are you forcing the browser to do work only to throw it away? The common cause of this in the past was sloppy event handling code where there was a mix of operations updating the DOM interleaved with calls which forced the browser to recalculate the layout (e.g. change the size of an element by changing its contents or formatting, call something which forces the browser to calculate its size, then repeating that cycle so the browser had to repeat the layout calculations it had just made – I remember things like layout code which is now obsolete thanks to CSS flexbox/grids having pathological states where that could happen dozens of times in response to a single update). That leaves plenty of room for differences from either of the scenarios you listed: for example, a library which doesn't use a virtual DOM at all can avoid all of the overhead related to managing one and diffing it but it has to keep track of its DOM elements to avoid needing to update all of them on any changes. This can be much faster and easy to write for simpler apps but has coordination challenges if your app gets large and especially if it has multiple teams working in the same codebase. The promise of React is that while it's never the fastest it'll be a reasonable balance for not being too slow while scaling up to larger teams.
- harel 4y agoSvelte is great. React is great. X, Y and Z are also great. And you know what they all share as well? Speed. They are all fast. Definitely fast enough for 99% of all uses cases if not more. The benchmarks they all provide are just benchmarks. I treat them like I treat car range reports by the car makers. I personally use react because I know it well, and it allows me super speedy development cycle once all the base components are done. I'm sure another person will say "I use Svelte because A, B and C". etc.
- metadaemon 4y agoI agree. Getting kind of sick of these posts that are thinly veiled political campaigns against the other framework. Great libraries tend to speak for themselves in terms of adoption. You shouldn't have to convince people not to use other options.
- ralmidani 4y agoIt’s not always bashing other frameworks gratuitously; an important aspect of human progress is recognizing what works well, what works less well, and what seemed like a good idea at the time but either became obsolete or was a bad idea to begin with. JSX and VDOM were at one time necessary (or at least helpful), but Web Components and Tagged Template Literals can do everything React does, only better and with less overhead (in both the developer’s mind as well as the computer’s runtime). I say that as someone who learned and taught bootcamps with React, and has yet to dive too deeply into lit-html and LitElement.
- lordgroff 4y ago100% There's a vanishingly small number of applications where it's really going to make a difference. Use what your work uses, or if personal project what you like. The more I use React and co. the more I feel like it's all the same thing.
- commandlinefan 4y ago> There's a vanishingly small number of applications where it's really going to make a difference Developers (and especially deadline-conscious managers) keep saying this, but their web sites keep slowing down my computer to a crawl. As a consumer, I really wish that development teams paid at least some attention to performance.
- deleted 4y ago[deleted]
- spankalee 4y agoThe key observation about HTML templates is that usually large portions of them don't change with new data. There is static content, and even with lots of dynamic bindings they're tied together in a static structure. So the vdom approach of processing all the static parts of a template during a diff is just extremely wasteful, especially for fairly common cases like conditionally rendering a node before some static content. Ideally you already know what changed, and can just update the parts of the template that depend on it. In JS that typically requires a compiler, complexity, and custom semantics (like Solid). But you can get very, very close to that ideal with plain JS syntax and semantics by capturing the static strings and the dynamic values separately then only comparing the dynamic values on updates. This is what we do with lit-html and why I think tagged template literals are nearly perfect for HTML templates. With tagged template literals, an expression like: html`<h1>Hello ${name}!</h1>` is passed to the `html` tag function as an array of strings `['<h1>Hello ', '!</h1>']` and an array of values: `[name]`, and the strings array is the same every time you evaluate the expression, so you can compare it against the previous template and only update the values in the DOM if it's the same. It's a really efficient way to render and update DOM with a pretty simple conceptual model that requires no compiler at all - it's all runtime. I think it's straightforward and powerful enough to be standardized at some point too.
- svachalek 4y agoI'm sure there's a different concept in there somewhere, but what you described sounds exactly like vdom.
- thomasikzelf 4y agoLet's call it vdata. Data diffing instead of DOM diffing.
- spankalee 4y agoThis model doesn't represent DOM nodes, it represents entire templates. And there's no per-node diff - you only compare bound values. So the structure of templates is entirely static.
- 4y ago
- deleted 4y ago[deleted]
- 88913527 4y agoPoorly written react code isn't performant and removing the Virtual DOM will not fix your problem. It's a hill I'm willing to die on. Many engineers seem to struggle with unnecessary re-renders, to the point where I see long tasks in the performance tab. Clicking a button shouldn't lock the UI thread for 2 seconds.
- CharlieDigital 4y agoI don't think that many junior/early mid React developers know that the whole tree gets re-rendered. Those that do, I don't think they fully understand when and where to `useMemo` and `useCallback` to optimize. It tends to get overused or used in a way that doesn't actually memoize the parts of the component that doesn't change. Then adding in state management only makes it more complicated in some cases depending on the state paradigm. It's a mystery that React is as prevalent as it is given how hard it is to actually do well. I think Solid.js and Vue have a much cleaner paradigm as far as re-renders goes (with React being explicit opt-out and Solid and Vue being opt-in).
- 88913527 4y agoYou're right. There is some cognitive bias, when I was a junior, I didn't lean on useMemo in the way I see today's juniors using it. The mis-applications revealed that some engineers don't totally get the paradigm, and that is a weakness. Most seem to get, at a high level, that "fn(data) = view" but then caught up of the weeds of unnecessary memo'ing to paper over performance issues.
- hbrn 4y ago> removing the Virtual DOM will not fix your problem Having seat belts will not fix car crash deaths. But it does make them less likely to occur, doesn't it?
- 88913527 4y agoI think if you take someone who isn't too skilled in React, and then give them a different framework, that you'll end up with too much different of a result. I don't write much Vue, so I don't know what performance issues there look like, but I do know it isn't discussed much since it has a much smaller market share. If going VDOM-less really is a silver bullet, I'd be curious to hear more.
- megaman821 4y agoReally they should just add DOM morphing into the DOM APIs. React has proved there is some value to this approach, whether it is speed or mental model, there are enough positives to just add it to the platform.
- revskill 4y agoRules of thumb is: - Make it work - Make it fast Reality is, most of developers just want to get shit done and go home. The bosses of course never want to pay you for "make it fast". The point of React is of course, low overhead JS class/function to decompose large UI. That made the job done.
- rk06 4y agoJs frameworks are also pure overhead. I have never seen any benchmark where they have ever been better than vanillaJs. /s
- robust-cactus 4y agoThere's no real benchmark for developer experience. Performance only matters up to a point. And it depends what you're building. If you're building pages where people just read content - sure - server render + vanilla js it. If you're building something more interactive where you think you'll have greater than 50k lines of JS prepare for pain. Last note - picking the right tool for the job is a quote we repeat often in the industry, realistically though that sort of optimization actually makes it harder to reason about writing code especially in a large org. The great thing about these frameworks is that it's a single way to build and you get server and client rendering. I remember back in the day folks would ask "how do you build a page here" and it would kill me to say "it depends I have 10 questions for you"
- rk06 4y agoYep, that's my point. The abstractions are a means to an ends. And are worth their overhead in many cases. So calling them pure overhead, for sake of performance, is absurd as calling js framework as pure overhead
- tekkk 4y agoLove Svelte but well, raw DOM manipulation isn't fast either. I have a recursive Svelte tree component which, as I collapse node's contents, destroys all of its children. Which is fine with small trees but once they get big there's a noticeable lag between collapsing/uncollapsing trees. Once I deploy the site it gets faster but still, destroying children components is slow. I think I'll try next just toggling visibility instead and skipping the removal of children. Sure this is a bit of edge-case but there's no definite silver-bullet here. Don't know about Svelte internals if this is something they could do eg hiding the components before destroying them. But well it'll still jank (but not as visibly) as everything is done in the same UI thread. Virtual list of course would probably be the optimal solution.
- c-smile 4y agoYes and no. Having implemented virtual DOM natively in Sciter (1), here are my findings: In conventional browsers the fastest DOM population method is element.innerHTML = ... The reason is that element.innerHTML works transactionally: Lock updates -> parse and populate DOM -> verify DOM integrity -> unlock updates and update rendering tree. While any "manual" DOM population using Web DOM API methods like appendChild() must do such transaction for any such call, so steps above shall be repeated for each appendChild() - each such call shall left the DOM in correct state. And virtual DOM reconciliation implementations in browsers can use only public APIs like appendChild(). So, indeed, vDOM is not that performant as it could be. But that also applies to Svelte style of updates: it also uses public APIs for updating DOM. Solution could be in native implementation of Element.patch(vDOM) method (as I did in Sciter) that can work on par with Element.innerHTML - transactionally but without "parse HTML" phase. Yes, there is still an overhead of diff operation but with proper use of key attributes it is O(N) operation in most cases. [1] https://sciter.com https://sciter.com
- SigmundA 4y agoJust have a suspendLayout resumeLayout / beginUpdate endUpdate method like Winforms surprised doesn't exist after all these years
- c-smile 4y agoNot so easy unfortunately. 1. BeginUpdate stops a control from repainting itself and that is what browser is doing already - no painting happens at the moment of JS execution. So primitive "postpone painting" does not really help. 2. element.update(callback) or DOM.mutate(root,callback) shall be a single method - no one wants EndUpdate() calls to be skipped because of errors thrown and the like.
- ncann 4y ago> no one wants EndUpdate() calls to be skipped because of errors thrown and the like. but surely with enough effort and care this should be a non-issue? And maybe auto-rollback on error?
- overgard 4y agoSadly, it seems like nobody is considering the best optimization: make DOM operations fast. I think if you could batch DOM operations together you could avoid a lot of wasted relayout and duplicate calculations.
- msoad 4y agoYou can't parallelize DOM updates. All has to happen in the main loop. This is not gonna change for the web as it is today.
- afavour 4y agoI don't think that's what OP is saying. They're saying that (e.g.) calculations are made on each appendChild() call when it would be more efficient (when you know you're going to be inserting a ton) to suspend all calculation, insert 1000 nodes, then resume calculations. Something akin to setNeedsLayout() on iOS: https://developer.apple.com/documentation/uikit/uiview/1622601-setneedslayout https://developer.apple.com/documentation/uikit/uiview/16226...
- nickpeterson 4y agoI good parallel might be database development, the difference between taking a cursor and looping through to make changes vs a set based operation that understands how to specify all the needed changes at once.
- overgard 4y agoYes, that's exactly my point, thanks for expressing it better than I could
- overgard 4y agoMy point is that if you change the DOM api itself thats the win. Right now its just individual property updates, so the browser can't know when to delay a computation. So definitely not part of the web today, but it seems worth considering.
- 4y ago
- deleted 4y ago[deleted]
- malinens 4y agoI haven't see any project which feels fast which are written in React. But most important thing for me which is broken (because it is too difficult to catch all edge cases) in all the JS frontends is the broken navigation (browser's back and forward almost never work as expected, bookmarking links are broken because state is in JS etc.)
- shadowgovt 4y agoThis can definitely be fixed (it involves making sure the relevant operations in the app manipulate `window.history` and either indicating location state in the browser via the hash portion of the URL or building the server to work hand-in-glove with subpaths), but it requires more work than the default navigation one gets with a multi-page app. I've seen good frameworks for managing this but I agree that developers tend to forget it.
- notshift 4y agohttps://twitter.com/dan_abramov/status/1135424423668920326 https://twitter.com/dan_abramov/status/1135424423668920326 Above thread summarizes the issue pretty well I think. Optimizing for DOM updates is nice, but you also want to optimize for bundle size and page load time, and at a certain app size the compiler output is always going to be bigger than just using a virtual DOM.
- hbrn 4y agoIt is true that Svelte and React bundles will grow at different speeds as the app grows. Redundancy gets compressed in React library, but it just stays there in Svelte. That said, since it is redundancy, I wonder if Svelte bundles are more gzippable (or at least, could be made so).
- notshift 4y agoAs far as I understand, in React, there is no redundancy to compress. You have one algorithm for diffing the virtual DOM and you're done. On a spectrum of biggest bundle size to smallest possible bundle size, the React model (more specifically Preact) would be as far to the right as you can go. Whereas any solution which does more specific compilation on individual operations to minimize DOM update work is going to have special code for each case.
- ruduhudi 4y agoCan we please talk about how much reactive programming sucks for UIs? I miss all the people who switched from angular to react for a reason in these discussions... I'd bet none of those are going to move to svelte.
- feoren 4y agoYes, please do talk about how reactive programming sucks. Because I've come to believe it's absolutely mandatory for keeping an advanced UI performant, mostly bug-free, and limited in technical debt. Absolutely mandatory. And yet I agree: it sucks. It sucks donkey balls. Why does this absolutely critical technology suck so much?
- renlo 4y agoI switched from Angular to React 8 years ago, and I've no interest in Svelte. If I recall correctly the primary problem with Angular was $watch, race conditions, etc, meanwhile with React your state is your state, purely functional and idempotent, which is a feature of "reactive programming". Reactive programming is fantastic.
- pcthrowaway 4y ago(2018)
- nailer 4y agoHonestly I feel like anyone that hasn’t written Svelte by now isn’t an active front end developer.
- pcthrowaway 4y agoState of JS disagrees
- nailer 4y agoNo it doesn't. https://2022.stateofjs.com/en-US/libraries/tier_list https://2022.stateofjs.com/en-US/libraries/tier_list https://2022.stateofjs.com/en-US/libraries/front-end-frameworks/front_end_frameworks_experience_linechart https://2022.stateofjs.com/en-US/libraries/front-end-framewo... https://2022.stateofjs.com/en-US/libraries/front-end-frameworks/front_end_frameworks_section_streams https://2022.stateofjs.com/en-US/libraries/front-end-framewo...
- horsawlarway 4y agoI'd argue this is essentially just an optimized (and therefore potentially more buggy) virtual dom. Svelte is being smart and skipping comparisons in the places it knows the result is static. That's nifty. But it also means you have to depend on svelte getting it right every time, in all scenarios. Long term - I think this is probably the right approach, but it feels very similar to the -03 c++ optimization flag: There was a fairly long period where enabling that flag was considered risky. Each extra transformation carries opportunities for bugs. It also means extra work at code generation time - it's building a vdom engine specific to your template (again - this is nifty!). Probably not a huge deal, since js build tooling is seeing a LOT of focus on speed, but it's there.
- ttfkam 4y agoTell us you've never tried Svelte without actually saying you've never tried Svelte. You would have likely not said this if you had ever looked at Svelte-compiled JS. The amount of mutation is surprisingly small and easy to follow. Especially when coming from a world with JSX.
- horsawlarway 4y agoSo what part of this statement do you disagree with? > "it's building a vdom engine specific to your template" Because that's... exactly what it's doing. It's doing it at compile time, and so yes - the amount of mutation in the output is small, which is not surprising at all because most templates are fairly static. We can quibble over exactly what a VDOM is, but I don't really know that tracking only a subset of the DOM the app might change (aka: svelte) vs the entire DOM (aka: react) really matters. In both cases you need to map changes to DOM updates, Svelte is just being smarter about it.
- ttfkam 4y agoI'm not sure we can quibble over the definition of a vDOM. There is the DOM as found in browsers and then there's a layer on top of that, proxying access to the DOM, which we call a vDOM. Svelte does not have this construct. All actions are performed on the DOM without an intermediary proxy object. Tracking 100% matters, because you must iterate through the vDOM to determine the diffs that must be applied to the underlying DOM. On every change to the vDOM. This is not free. It is why the following abstraction leaks exist in React: • shouldComponentUpdate • React.PureComponent • useMemo • useCallback This is making the developer worry about things the computer should've be able to suss out for itself. You expressed concern that Svelte's compiler approach is new and therefore subject to bugs. Aside from Svelte being over 6 years old now and having gone through 3 major versions already, my assertion is that any potential bugs present in Svelte's compiler at this point pale in comparison to the number of potential (and actual) bugs or performance gaffes present in the equivalent React app due to excess lines of code, complexity, and abstraction leaks such as those listed above. The cognitive overhead is real and has a measurable effect on developer output. Bugs are proportional to number of lines of code regardless of the language being used. I assert that we developers, people, human beings, are far more fallible in this regard as to render concerns about the Svelte compiler's accuracy relatively moot. This is analogous to the switchover from Assembly to C. Early C compilers certainly had their issues, but even in the earliest days, the increase in productivity and reliability as a whole far outweighed the benefit of manually generating all instructions at that lower level. Even though today there are still optimizations to be made from analyzing hotspots and replacing generated code with assembly in those few spots, the compiler-first approach stills wins out because 90%+ of the time, it does as well or better than the hand-crafted Assembly... err... React code can in a tenth the developer time simply because compilers are now and have always been better than human beings at managing rote development tasks. Rote as in flagging variables for reactivity, (un)subscription to stores, accessing data properties, handling data binding, marking sections as immutable, etc.
- pweissbrod 4y agoIn more cases than not I've noticed the choice of single page app itself is pure overhead. SPA technology brings some key advantages but also a whole new realm of cost and complexity. It's my experience that SPA popularity has convinced many folks to use it when they really don't have a practical reason to justify it.
- com2kid 4y agoSvelte is so insanely lightweight, I think it is a great counter argument to a lot of the SPA hate. And honestly, most of the weight in modern websites comes from analytics and tracking tools. I've made insanely performant SPAs that work well on low budget hardware. My personal phone is 5 years old, if code I write doesn't perform flawlessly on it I'm not going to ship it to customers! Heck my personal dev laptop is a 4+ year old $999 Costco special. Well made React sites can run just fine on devices like that, and Svelte runs even better. Also SPAs scale better, I remember the days of website backends being slow, with page loads taking forever, massive amounts of HTML being generated server side using slow scripting languages. Sending a JSON blob of some fields to the browser and having the browser update some nodes makes a lot more sense than the old school way of reloading the entire bloody page to change a couple fields.
- pweissbrod 4y agoBy choosing an SPA. You must choose a dedicated static site hosting which is separate from your web application. You may already have this but you may not. In most cases you must choose a framework for routing. Also a framework for state management. You also dedicate to duplicating validation and security trimming logic both on the client side and the server side. More often than not you will find yourself including hundreds of NPM packages as dependencies which you must continually update and maintain. Also the requirement for unit testing on the front end is common. Which brings in the need for things like jest and enzyme. This complexity inevitably trickles into your build and deploy processes. Perhaps in larger teams this is a burden you can absorb. In smaller teams however you start to see division of responsibilities. One person only knows front end but not back end and vice versa. Common knowledge of the application as a whole can become fragmented. Perhaps the day comes where you want to take a partial of a user interface posted in a peripheral application and place it inside your web page. Because you have a virtual DOM this is now a security risk. You must build a component which duplicates the user interface which already exists. If the user interface needs to be shared among many applications you must build a commons code base to host your components. You start shouldering the burden of maintaining component libraries instead of just HTML and CSS. Again this is all very general and hypothetical but it feels worth pointing out some of the common implications that simply choosing an SPA can have in the longer run. Plus this is not an all or nothing sort of choice. For decades we have used Ajax to perform partial updates on a web page. Consider alternatives like HTMX as a comparison.
- aranchelk 4y agoI take “pure overhead” to mean a cost with literally no benefit. To me that just makes it sound like Svelte is being pushed by idiots, because clearly there’s a substantial benefit (regardless of whether or not VDOM is an optimal strategy). From the end of this article: “Virtual DOM is valuable because it allows you to build apps without thinking about state transitions, with performance that is generally good enough. That means less buggy code, and more time spent on creative tasks instead of tedious ones.“ Okay great, it’s not pure overhead.
- mistersys 4y agoNo need to be pedantic. He's obviously saying that there are better strategies then vDOM with lower overhead. This is proven by Solid.js which is faster then every VDOM framework, has an API that is functionally the same as react, and doesn't use VDOM.
- Rapzid 4y agoI believe Solid has also kinda shown that.. Well, I like its low-touch approach compared to svelte's need for heavy compiling and a new language essentially. With Solid can use JSX and it doesn't even need, last I checked, anything beyond standard JSX transformation to get pretty good results. It's the better direction IMHO even if the Solid APIs feel like they need another iteration or so.
- taftster 4y agoWe live in the era of click-bait titles and these manifest even by, what you would hope, are more reputable establishments. The author obviously agrees with your sentiment (given the quote you cited), but it's too easy and just the norm to be hyperbolic in your blog title, articles or essays.
- klysm 4y agoIsn’t svelte essentially just a cached vdom or do I have the wrong mental model
- SebastianKra 4y agoCalling the VDOM pure overhead is a strong statement when there are patterns that are more difficult to express in Svelte because of how it manages views. Once a view is created, it can't be processed by JS. It can't be stored in an array or an object. You can't count or individually wrap children. This makes it harder to create flexible API's [1]. The question is: are we willing to give up the expressivity of React for extra performance? I am leaning towards "no", because I believe React's performance issues mainly come from its memoization-based reactivity model rather than the VDOM. When applying `.useMemo` in the right places I can create perfectly performant apps. However, this requires profiling and is often unintuitive. [1]: for example https://news.ycombinator.com/item?id=33990947 https://news.ycombinator.com/item?id=33990947
- Rapzid 4y agoMobX and chill. Seriously though, modelling the FE business logic entirely outside the view library and just wiring it up to observables where necessary is extremely refreshing, maintainable, and FAST.
- ironmagma 4y agoAnd having a custom JS compiler isn't pure overhead?
- ttfkam 4y agoAre you calling a C compiler overhead as well? Ahead of time compilation is not runtime overhead, and for users of the web, runtime and network latency are all that matters with regard to the perception of speed.
- ironmagma 4y agoMental overhead matters much more than performance overhead to most applications. The whole plot of JS is that it’s easy enough to work with that it overpowers any performance limitations. Svelte invents a completely new execution model for JS which adds overhead.
- ttfkam 4y agoI honestly don't believe you've actually used Svelte even in an experimental context to make such a comment. Go check out the tutorial on the Svelte site and get back to us. It's literally >90% just HTML, CSS, and JS. The last <10% is split between stores, if- and each-blocks, and data binding syntax. If you don't know HTML, CSS, and JS as a web developer, I don't know what to tell you. If you do, the notion that Svelte has a substantial mental overhead compared to any other web framework—especially React—is utterly ludicrous.
- ironmagma 4y agoAnd that’s similarly how I feel about people who think Svelte is significantly less complex than React. At least React is just Javascript. Svelte tries to override assignment to trigger side effects. That’s crazy.
- imbnwa 4y agoAren't Hooks also a significant deviation from the JS execution model? That they needed to write whole new documentation to clarify the model and its application seems to speak to some deviation
- naikrovek 4y agoI absolutely love articles like this. Written by people with more critical thinking skills than technology fetishism. Great to see.
- dang 4y agoRelated: Virtual DOM is pure overhead (2018) - https://news.ycombinator.com/item?id=27675371 https://news.ycombinator.com/item?id=27675371 - June 2021 (289 comments) Virtual DOM is pure overhead (2018) - https://news.ycombinator.com/item?id=19950253 https://news.ycombinator.com/item?id=19950253 - May 2019 (332 comments)
- divan 4y agoIs there any discussion in webdev community whether using typesetting engine from 80s is even a good idea for modern performant UI apps? Or it's just taken for granted and never questioned?
- dangoor 4y agoI don't think that perspective is fair to modern browser engines. The additions of flexbox and grid layouts took them beyond just typesetting, I think (not to mention all of the work on JS engines, providing APIs for a whole bunch more device functionality, etc.) So it's true that there's still a "typesetting engine from the 80s" in there, but there's also a powerful layer of app functionality built-in as well. It's reasonable to question whether all of this belongs together, but all of this evolution _has_ allowed for whole new classes of applications to be delivered securely and quickly to all sorts of devices in the browser.
- divan 4y agoAs a thought experiment, imagine that we would have started with Lotus 1-2-3/Excel type spreadsheets instead of formatted text. I believe that we would develop tons of layers of abstraction on top of this too, in order to make cells and functions to emulate UI framework. It would probably work as well, and had some weird quirks related to the cell-based nature of this super-powerful engine. Yet, the question remains - would it be a good foundation for modern UI apps? To me, most of the issues with web apps stem from the fact that foundation is just not built for that task. Like these weird selection issues, where you move cursor 1 pixel more to the bottom and it selects the whole visible area instead of text - that doesn't even make sense. Or jumping page and blocks all over the page while it loads fonts and stylesheets. Sure, we build more hacks on top of existing hacks to mitigate this, but that's just duct taping with complexity, not the engineering.
- taftster 4y agoRight. It's been discussed before, but the web browser is one of the greatest examples of "write once, run anywhere" in terms of the markup that is HTML. If the evolution had happened differently, maybe we'd be all be using Java applets or Flash applications instead. I believe HTML/browser is superior, but I wonder where other platforms would have evolved to.
- szastamasta 4y agoFor me, whole DOM is a useless overhead. Why don’t we just have some nice transactional browser API? Client side frameworks don’t really need to generate HTML that is immediately parsed. It’s a total waste.
- shadowgovt 4y agoI was thinking about this recently while teaching a student how to make a page that captured a camera's MJPEG feed. ... it's real hard to get past the simplicity of "Just change the URL property to a new value" that the current DOM API provides. Losing that would suck.
- vbezhenar 4y agoI can't trade TSX for any text templates. Being able to write tags and having them syntax-checked with types support is indispensable. I wish that those frameworks embrace TSX rather than trying to drag users to the dark past.
- brap 4y agoIMO, TSX really is beautiful, I can’t see how it can be beat. I’m not a big fan of how React handles state and effects, but TSX itself is joy to work with.
- toastal 4y agoI'd rather type checked functions that don't have to futz XML syntax and unexpected incompatiblities with HTML while superficially looking similar. A lot of compile-to-JS languages that don't have a the C-like syntax, the results are highly legible which being more condense and not require a separate parse/compile step.
- nailer 4y agoSvelte supports TS.
- peterhunt 4y agoI'm quoted in this blog post so I figured I'd respond. I'm a former member of the React team but I haven't worked on it in a long time. Largely I agree with everything in this article on a factual basis but I disagree on the framing of the trade-offs. Two points in particular: 1. Before open sourcing React we extensively measured performance on real world applications like mobile search and desktop ads management flows. While there are pathological cases where you can notice the overhead of the virtual DOM diff it's pretty rare that it meaningfully affects the user experience in practice, especially when compared to the overhead of downloading static resources like JS and rendering antipatterns like layout thrash. And in the situations where it is noticeable there are escape hatches to fix it (as mentioned in the article). 2. I disagree with the last sentence strongly. I would argue that Svelte makes huge sacrifices in expressive power, tooling and predictability in order to gain performance that is often not noticeable or is easily achieved with React's memoization features. React was always about enabling front-end engineers to take advantage of software engineering best practices so they could level up velocity and quality. I think Svelte's use of a constrained custom DSL is a big step backwards in that respect so while I appreciate the engineering behind it, it's not a technology I am interested in using. Even though I disagree on these points I think it is a well-written article and is a pretty fair criticism of React outside of those two points, and I could see reasonable people disagreeing on these trade-offs.
- norswap 4y agoAs a seasoned engineer (compiler background), but beginner in frontend, I'm curious aboutthe lack of expressive power that Svelte incurs. Could you (or someone) characterize things that are hard to do in Svelte?
- SebastianKra 4y agoOnce a data is transformed into a view in Svelte, you can't do anything with it in JS. For example, a component can't iterate over the children in a slot [1]. This is limiting when designing generic Component-APIs. As an extreme example: In React, I could trivially define a tabbed interface by mixing strings, JSX, and components, without imposing any DOM-structure. The component that reads this definition could use it to build a tabbed-view on mobile, and a master-detail-view on desktop. ...or it could build a table of contents. When defining the tab names, I can mostly use strings, but fall back to JSX if necessary. Importantly, the API is completely independent from the implementation. const tabs = [ { name: "Tab 1", icon: <img ... />, content: MainTab }, { name: <>Tab with <b>bold<b/> text</>, icon: <MyIcon ... />, content: SecondTab }, ] return <MyLayout tabs={tabs} /> [1]: https://github.com/sveltejs/svelte/issues/5381 https://github.com/sveltejs/svelte/issues/5381
- PaulDavisThe1st 4y agoReading this as a native developer is a bit like reading about alchemy or astrology - two fields with their own vast suite of terminology and internal logic that doesn't fully correspond to anything real ... ... only to find out that this stuff is actually real and is how a big chunk of the visible web actually works.
- c-smile 4y ago> native developer You probably haven't done any native UI as native UI uses exactly the same idiom. CWnd* parent = ... parent->appendChild( new EditBox() ); native UI also uses DOM concept, it is just that instead of child elements it uses term child windows or [Gtk]widgets or [ns]View s.
- PaulDavisThe1st 4y ago> You probably haven't done any native UI Hah. https://github.com/Ardour/ardour/tree/master/gtk2_ardour https://github.com/Ardour/ardour/tree/master/gtk2_ardour ... c'est moi Anyway, that's not really the point I was making. Native UI can be thought of and used as a DOM model, but that's not inherent to the process unless you're literally writing traditional database+presentation+edit applications. I was more poking light-hearted fun at the explosion in terminology and concepts exposed to someone doing web-based "frontend" development, and how little most of this has to do with HTML, CSS and the general classical model of "a browser".
- tsss 4y agoCome back when you know about HWND, boy.
- TheRealPomax 4y agoNote that a virtual DOM is pure overhead if you already have a real DOM to work with. That's kind of the ignored superpower of a framework like React, which makes the virtual DOM the authority: there might be a DOM, but there also might not be. Whether the virtual DOM reflects to a real DOM, or native UI, or Qt, or an ASCII terminal interface, it doesn't care. This is also the part that most web devs have the hardest time with: React (and some other frameworks) are not web frameworks. They really are just UI frameworks, that happen to (also) work in a browser. Even if they were original born out of a web need way back when.
- MrOwnPut 4y agoWhy did I have to scroll this far down for the real answer? This is the true power of the VDOM, to abstract the view from platforms. Why be a web developer when you can be a cross-platform app developer? That's why I don't use Svelte and other web SPA frameworks...
- revskill 4y agoThe point is, if you want to make your web app the most performant as possible, cross-platform solution has limitation.
- TheRealPomax 4y agoAbsolutely, but conversely: the performance hit of the virtual DOM _should_ (and that's doing a lot of heavy lifting) be irrelevant in a well designed UI, because aside from initial load, most parts of the UI don't change for the majority of the lifetime of the app. Only tiny portions of the UI update at a time. The parts that do update can most definitely update fast enough on even moderately modern hardware (both desktop and mobile). That does, however, require having properly designed your UI, with a knowledge of where the power of your framework of choice is. And that's where a lot of apps fail. Even something as simple yet critical as using vdom keys tends to (for various reasons) never register for many folks, leading to terrible performance.
- MrOwnPut 4y ago
- rglover 4y agoIf that's true, then what is needing a custom compiler for your components to work?
- intrasight 4y agoI've heard the term "virtual dom" for years. This article made me want to understand. It gives this example for explaining "what is a virtual dom?" function HelloMessage(props) { return ( <div className="greeting"> Hello {props.name} </div> ); } And that returns "an object representing how the page should now look" Aren't we developers here. How about an object type. I assume it's a DocumentFragment. Is that correct? Then it talks in broad (i.e. useless) terms about using this object. So my next question is: what's exactly is wrong with using a DocumentFragment to just replace that part of the DOM? For example: let frag = renderMyModel(); if (destElt.firstElementChild) { destElt.replaceChild (frag, destElt.firstElementChild); } else { destElt.appendChild (frag); } I do this with a massive DOM tree and rendering is like instant.
- MrJohz 4y agoI don't think that's a great explanation of the concept of VDOM. For example, SolidJS looks a lot like the example given, and it also arguably returns an object that represents how the page looks, but it didn't use a virtual DOM under the hood. I think it's easier to think of virtual DOM implementations as doing two things: (1) describing the desired state of the DOM in some sort of structure, and then (2) diffing that structure against the actual DOM in order to make the changes. The key part is that the virtual DOM implementation does the diffing itself in order to make the changes itself. This is similar to your example, in that you have generated the desired tree and are rendering it in the right place. However, it is different, because the browser will not do a fine-grained diff of all the elements, it's just going to replace them with the new elements that you've given it. This works fairly well if you're trying to replace a large chunk of elements with a new set of elements, but it has problems if you just want to make smaller modifications. For example, consider some JSX for an arbitrary framework that looks something like this: function MyInput({ isGreen }) { return <input class={isGreen && "text-green"} /> } When `isGreen` changes, we want to update the current value of the DOM with the new version of MyInput, which should just be the same thing with the class changed. The naive (although often simplest and most practical) solution would be to just replace the contents of the element with the return value of MyInput - i.e. replace the input with a new copy, just with the class name changed. The problem comes when a person is typing into the input - if we replace it completely, the use will lose everything they've already written. The VDOM solution is, as I said, to (1) generate, but then (2) to diff. So if the current state is an input with a "text-green" class, and the desired state is an input without this class, it would work recursively: First, is there an element? Second, does the element have the right tag name? Third, for each attribute on the two elements, do they have the same values? Etc. And every time there's a change, it will make the smallest change possible to ensure the current state becomes the same as the desired state. Here, that means removing the class name, but leaving the rest of the input as it is (i.e. with any input from the user left alone). The third option here is what frameworks like Svelte and SolidJS do: they skip the part of the process where you generate a new desired DOM, and jump straight to the diffing. That is to say, when you create a component, inside that component will be event listeners for each part of the component that needs to change (and only those parts). This listen to changes in the props and state and then change only those parts of the DOM that need to change. That way, you don't need to go through the entire DOM, iterating through all those nodes that stayed the same just to find the class that needs to be updated. Instead, you just directly update the class.
- sub7 4y agoIf I see html in a javascript file, I boycott the codebase
- nailer 4y agoSteve is is HTML in a .svelte file, React was HTML in a .jsx or .tsx file. I’m going to assume you’re boycotting neither or both.
- fleddr 4y agoImagine being someone in the semiconductor industry reading this. You're at the absolute pinnacle of high-tech and are approaching the limits of material reality to realize a 20% faster CPU. It's a true super human accomplishment. Software developers: well yes, 99% of the cycles I use are completely needless, but it's still plenty fast enough! Which we justify with the idea that a framework like React is abstract, hence expressive and productive. Excuse me? Abstract? React is absurdly low level. 25 years ago I was coding in Borland products. You visually drag you UI together. Link events with a click. Drag data sources and fields into UI to do two-way binding. Tooling chain? What tooling chain. There's a build and a run button. No weird text config files or CLI crap. And every setup is the same. 25 years later we're worrying about painting frames. We're pissing away impressive hardware performance whilst simultaneously not actually achieving abstraction. That's a double fail.
- satvikpendem 4y ago"What Andy giveth, Bill taketh away" https://en.wikipedia.org/wiki/Andy_and_Bill%27s_law https://en.wikipedia.org/wiki/Andy_and_Bill%27s_law
- fleddr 4y agoGood one, did not know that law but it's on point.
- deleted 4y ago[deleted]
- postalrat 4y agoDid the borland apps you developed 25 years ago handle all sorts of devices and screens including screen readers?
- fleddr 4y agoDoes any web framework do that? No, you have to do all of that from scratch.
- 4y ago
- onion2k 4y agoMy life, and blood pressure, would be greatly improved if every article about JS frameworks ended with a paragraph that says something like "... but JS frameworks are pretty fast really, so you'll only see a problem if you're changing lots of things on the page at once. And if you're updating lots of DOM nodes in a single action then maybe you need to think hard about your underlying HTML structure and UX instead of worrying about what JS is doing. That's where your problem lies after all."
- ttfkam 4y agoRethinking Reactivity by Rich Harris (2019) https://youtu.be/AdNJ3fydeao https://youtu.be/AdNJ3fydeao
- rwalle 4y agoAn article that talks about performance and "fast" and "slow" but does not quote a single benchmark? Sorry this is nonsense.
- flangola7 4y agoAnything beyond HTML and CSS is a mistake.
- WirelessGigabit 4y agoIn the first example showing the diff of JSX and React.createElement: > You can do the same thing without JSX... Well, the end result is that there is no JSX. It's gone. It's syntactic sugar.