Virtual DOM is pure overhead (2018)
svelte.dev
svelte.dev
If your app is spending a significant amount of time doing virtual DOM diffs, then sure. The virtual DOM overhead is a problem. However, saying it’s pure overhead and then not qualifying how much is a catastrophic failure of reasoning. Their alternative is to add more complex compiler steps, which I’m sure could work great. However it’s awfully dogmatic to suggest that this is better simply because it eliminates one kind of not-strictly-necessary overhead.
Svelte probably hasn’t taken over because the real world isn’t synthetic benchmarks and most apps have more significant concerns than how many times a component can update per second - and even then, in my experience React is more than capable of doing a decent job here. In practice. So Svelte has a lot to prove to get people to try to move. And this article categorizes virtual DOM as a “meme” that is “pure overhead” that only wins against a “strawman” (while simultaneously admitting that plenty of frameworks were slower at the time.) That’s not going to work. That’s going to classify you as “insane person” to many people. It reminds me of the claims G-WAN made: over-exaggerations in a smarmy tone based on micro-benchmark wins.
I’m not saying there’s anything wrong with Svelte. But, this is not how you sell something. React sold us the idea that the virtual DOM could give us a better programming model and still outperform the template based frameworks of the day. It delivered exactly that. And yet:
> the alternative is to do something no-one actually does
Somehow this article manages to contradict itself in pursuit of unnecessary smarminess.
I know this article is from 2018, but it never landed well for me, and Svelte’s virtually unchanged irrelevance should be some kind of cautionary tale. I don’t think there is anything wrong with Svelte. But this isn’t how you sell a framework to programmers, in my opinion.
The irony is that Svelte compiles code that will then run on a JIT under a JavaScript engine. That’s strictly overhead.
The part that I think the article misses is that VDOM is just an implementation detail of React. No one actually really cares about it, and its not the reason why people use React.
It's important to understand that virtual DOM isn't a feature. It's a means to an end, the end being declarative, state-driven UI development. 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.
But it turns out that we can achieve a similar programming model without using virtual DOM — and that's where Svelte comes in.> It's important to understand that virtual DOM isn't a feature. It's a means to an end, the end being declarative, state-driven UI development.
I find this bewildering because it makes me feel like the article does actually understand React. It realizes it was faster than frameworks it initially competed against, it understands that virtual DOM is a means to an end. But then at the same time it is classified as a meme that only wins in performance against things nobody would ever do.
In a way, writing it like this makes it harder to critique.
At the end of the day, I've never spoken to a developer who was using React because it was fast, but because it was easy to use and understand.
If Facebook comes up with something else, I think it will be something new. Maybe that is Reason, or something that abuses WASM/Rust in the core architecture. Who knows. The project has a lot of tech debt, and the ecosystem has changed quite a bit as well.
Svelte’s approach requires detailed knowledge of the structure of state, and requires compilation: components’ <script> blocks are not written in JavaScript, but rather a language with the same general syntax but different semantics, and some places where JavaScript is too flexible to be tractable get replaced with special template syntax (like {#each} instead of for-loops or Array.prototype.map). Svelte cannot be implemented as a JavaScript library (I disqualify eval()). Svelte is also deliberately severely limited in what it can express in various places, whereas React gives you the full power of JavaScript (for better and for worse).
You could perhaps implement an optimising compiler for a small subset of React components that avoid problematic patterns and are written in TypeScript with proper specifications of the types of state and props; but if you considered it unacceptable for this compiler to change the component’s semantics, I think you’d be surprised at how little serious React code in the wild could actually be supported. Even simple loops might be out of reach. The Svelte approach can’t be a progressive enhancement, it’s an all-or-nothing (at the component level).
One could argue that React's hooks are the same: they look like JS but change JS semantics.
However, your point is still valid.
The article is about VDOM and nothing else. It does not "miss" the part about why react is popular, it simply does not discuss it.
This is probably true today, especially for newcomers, but the article is from 2018 and the context of the time period is significant here, I think.
Having used React since around 2015, there definitely was an aire of "React is fast because of the Virtual DOM!" and it was one of its big selling points early on. I can remember reading this article and nodding along, but reading it now evokes more of a sense of "I remember when VDOM mattered". I think around that time was maybe the tail end of VDOM being a big selling point, and this article might've even precipitated that, to a degree.
As React's usage has grown, I think the significance of VDOM as a feature has fallen by the wayside in favor of things like "everyone uses React so we use React too." The competition between frameworks at the moment seems less about performance and more about their approaches and tradeoffs.
React gave us not a better programming model, it gave us an other programming model. In some cases template based enignes are better than JSX, but that discussion has nothing todo with Svelte or React.
React boomed cause at that time everybody has enough of bloated frameworks and with JSX you had a wonderfull thing to tinker code... thats what developers like, tinker all the day complex bloated code. Why made it easy, when you can have it complex? ;-) And it came from well known Facebook, thats it, nothing more.
I rememnber the day when everybody was shouting, Redux is the best thing every ;) And now "hooks" Really?
You can keep telling yourself that React only took over because it makes things more complex and it came from Facebook, if that's what makes you happy.
On their machines.
That's often a critical distinction. Developers often get the nicest computers, and they often get to have good, fast Internet connections that are close (in terms of Internet topology) to the server where the site is running. So they can't necessarily perceive the effects of the browser being starved for resources, or jank from the app being chatty over a high latency connection, or resources failing to load due to a spotty connection, or anything like that.
What some of these technical decisions add up to is situations like a family member who's using a cheap Chromebook and has flaky Comcast cable internet, bewilderedly asking me why this site they're trying to use keeps showing them a blank page or somesuch. They know that, if the page doesn't load at all, the browser usually gives them a, "We couldn't load that page. Try refreshing," error. What they don't get is that, if it's a React app and some JS resource fails to load, it'll stop the rendering of the site cold, and they'll just see a blank page, or a half-loaded page, or some other confusing state. And I've yet to figure out a way to explain things to them that gets them to see this as, "The Internet is being flaky." They see it as, "Your site is flaky."
They're not entirely wrong about that. The people who develop Internet and Web standards have put a lot of time trying to engineer the Web to tend toward failing gracefully. React (and frameworks like it) seems to have, in one stroke, undone all that and instead engineered things to tend toward failing catastrophically.
I don't know if you could get a JS-first framework that doesn't behave that way, so maybe it's a necessary evil? But, I get that React solves a real problem that some people have, so it'd sure be nice if it weren't.
React, imo, is about the programming experience. "Thinking in React" is a lot more than just VDOM, and the benefit of "thinking in react" is about the developer experience not the pure benchmarkable output.
Svelte has been around for a few years now - and I've yet to see/hear about an application built with Svelte at scale.
The reason I think React works so well and is so popular atm is because it works just as well at a small scale as it does on a team with 5-6 active contributors (in my experience, at least).
That isn't to say that Svelte can't deliver the same wonderful experience at scale, I've just yet to see a truly shining example of it.
I may also be in the minority, but performance of front end frameworks is near the bottom of my evaluation checklist.
I've used svelte for some one off personal projects, just to get a feel. And it's fine but nothing about has convinced me to lead a project/team towards picking that over React, Vue, or even some SSR framework.
When you start or build a new product/team and can freely choose which Framework you want to use, you can have a look at Svelte.
For our company Svelte is easier to use, it has (in our opinion) less bloated code (e.g. state handling) in our app as React or Vue (which we used before). BUT, Svelte has other problems, especially when you heavily use dynamic components, which are easier to handle in Vue or React.
That React has better active contributers is one big point for React. But it depends on Facebook.
Do you have an example?
Sorry to pick on this point but depending on your application this should be more (or much more) important. Too many teams have this same opinion and it's glaringly obvious how little they care about performance. I'd agree that raw performance isn't really important, but the ways you can and the tools you have to optimize the performance of the app are if you find that you have bottlenecks is and this does partially depend on the framework.
That said, I would agree, all frameworks would probably be fast enough for most use cases, and even with the optimization aspect arguably the most important aspects are about application structure and how the framework forces you to structure your application. As you mention, I think this is why React wins, the way it forces you to think about things unidirectionally, think about state and components separately, etc. are all big wins for understanding your application.
Also worth noting is that Svelte doesn't really have a big company backing it like React does and so the ecosystem is smaller, which could contribute to its relatively small size.
I've been working in React for ~4 years now, at all types of scale. While I've definitely seen performance issues, it's never been a case of a flaw in the approach the React takes.
I guess a better way to phrase my point - until I encounter a scenario where the performance is bad enough in React to warrant looking at other frameworks, choosing a framework based on pure performance is an over-optimization.
Of course, this would be a different conversation if React was known for being the one and only bottleneck in web app performance - but afaik that is a rare case.
What do you mean 'at scale'. It's a UI framework that runs JS and mutates the DOM - there's no issues with 'scale' here.
That Svelte isn't popular is because some frameworks get popular and go viral and others don't. That's it.
Svelte vs React on a single side project I work on in my free time by myself is different conversation than Svelte vs React on a team that's moving fast and has more than a single dev.
I understood what you meant, I just disagree that this is a real consideration. Both are just UI frameworks following modern conventions in architecting your SPA code-base. From that point, both are just fine. Other considerations, like the fact that React is more popular and therefore more likely to be supported in the future, and therefore has more devs familiar with it, are way more important.
This is complete and utter nonsense. Were you programming seriously before React? There were like 50 popular frameworks all competing with each other and no one framework dominated. React has completely taken over because it provided a dramatically better developer experience and solved a lot of hard and very real problems. As an incumbent it has staying power because there is benefit in sticking with the herd, it remains a pretty nice developer experience, and because it has essential features other frameworks don't really provide yet (React Native being the biggest one although I do realize other frameworks are working on this now too).
Svelt isn't popular because to disrupt a solid incumbent you need something that is dramatically better at solving problems devs actually care about (not corner case performance benchmarks when React is "good enough" 99% of the time). Svelt has failed to do that, plain and simple.
Dismissing Svelt's success/failure by saying all framework success is because of fads is an excuse and, if you are part of the Svelt community, maybe is a clue as to why Svelt has failed to be sufficiently introspective in either accepting it is a niche framework (which maybe it is great for) or that it needs to change if it wants to be more mainstream.
Indeed I was.
>There were like 50 popular frameworks all competing with each other and no one framework dominated. React has completely taken over because it provided a dramatically better developer experience and solved a lot of hard and very real problems.
I'm not saying React isn't a good framework, it is perfectly nice, though I think you're overstating it. AngularJS was a perfectly fine framework as well, and that was out long before React.
>Dismissing Svelt's success/failure by saying all framework success is because of fads is an excuse and, if you are part of the Svelt community
I'm not part of Svelt's community. I haven't actually used Svelt at all. I barely know about it. But I've been around for a while. Why certain frameworks go viral and others do not, is not always based on merit. I'll buy the argument that Svelt doesn't have enough of a benefit over React ... it also came out a few years later and doesn't have Facebook's marketing weight behind it either. Does that mean React is the best thing ever? Eh, it's alright. Having done everything from Flash/Flex/Starling, to Silverlight, to Backbone, to AngularJS, to React, I actually get more excited about State management patterns than widget overlays with some declarative patterns and data-biding. By the way, when it comes to ergonomics of building complex SPAs, I think we're just hitting the place that Flash/Flex was 15 years ago in Web Development.
And it still is. Mixing JS and HTML/DOM does result in fragile code and you shouldn't do it. React VDOM and JSX is not the same thing .. at all. Again, JSX isn't new. XML-based declarative UI frameworks with data-biding were an old thing by the time React arrived on the scene. That's how Flash Flex (MXML) and Silverlight (XAML) worked, for example.
It basically embodied the bad side of JS frameworks pre-React.
It managed to take alllll the wrong lessons from Flex.
Large teams were using jQuery back in the day, with none of that HMR prettier-on-save Redux devtools fanciness. There's nothing inherently "unscalable" about the technology, especially now that most frameworks more or less use the same framework design paradigms.
> nothing about has convinced me to lead a project/team towards picking that over React,
This is just a cost of switching consideration. For better or for worse, first movers advantage is a thing. You're also not likely to switch from date-fns to dayjs or postgresql to mysql because you are invested into your choice of technologies, even though each pair might in theory be perfectly interchangeable.
I think what people mean when they say “at scale” is they want to see a large codebase, with a large team working on it, where Svelte is the primary front-end choice.
One of the lead developers of Svelte uses it at the New York Times on some of their high traffic interactive data visualization pages, including their COVID charts.
Svelte's main point is that the performance claims of frameworks like React are just bullshit marketing-speak. That I agree with it. The value of JS UI frameworks in general, isn't in performance, but rather to provide a "declarative, state-driven UI development" because raw JS/HTML/CSS development is terrible and makes it easy to make terrible architectural decisions and write unmaintainable spaghetti code. In this way, whether you go with Vue or React or Angular, it makes no effin difference to performance.
But yes, there is overhead in managing the virtual DOM and yes, you can get yourself in trouble if you don't structure your application in line with how the framework expects you too.
>React sold us the idea that the virtual DOM could give us a better programming model and still outperform the template based frameworks of the day.
React made a stronger claim. It wasn't just about React vs some Templating framework. React tried to argue that direct DOM mutations are expensive and that using virtual DOM will yield more performance. As a general claim, that is a bullshit claim.
>Their alternative is to add more complex compiler steps, which I’m sure could work great. However it’s awfully dogmatic to suggest that this is better simply because it eliminates one kind of not-strictly-necessary overhead.
And it's not a bad argument. The DOM is an abstraction and the underlying implementation is highly optimized. DOM mutations are not the expensive thing, it's the final render, and that part has had an enormous amount of work done to make it smart and fast. By the way, Flash had a great built-in rendering model. The Flash display list hierarchy was very well architected and it wouldn't re-render the entire page if only a part of it changed.
>But this isn’t how you sell a framework to programmers, in my opinion.
Claiming your framework is faster than the other guys IS how you sell a framework to programmers. That's how React and Vue were/are being sold.
Virtual DOM comes with a different set of trade-offs in terms of needles and haystacks. If you have lots of mutations relative to the size of the DOM, then virtual DOM overhead per mutation is relatively low. But if you're only updating a single element in a very large tree, then you are incurring a lot of overhead per mutation.
Another modern confounding factor to be aware of is that some browsers (notably Chrome) have made it so that mutations through the DOM API no longer cause a repaint to block the main thread (which is how every UI system ever should work, really). What this means is that any performance benchmark that uses JS APIs to measure UI responsiveness is going to be problematic (either by not measuring repaints correctly, or by adding a ton of confounding factors by shoving the macrotime queue of setTimeout/friends into the measurement)
Also, qualitatively, there's different levels of overhead. A repaint takes in the order of hundreds of milliseconds (i.e. it can be noticeably expensive). DOM API calls are also "expensive", but only in the order of a millisecond or so; you do want to touching the DOM unnecessarily if possible and virtual dom helps avoid silly mistakes like re-querying the DOM on every event like in the `$('.foo').on('mousemove', () => $('.bar'))` anti-pattern. Virtual DOM is "overhead" in the sense that allocating memory for a virtual DOM node is "expensive" (compared to not allocating any memory). But we're in microsecond-per-instance territory at this point. You need large haystacks with very small needles at high frequencies in a slow device to experience human-noticeable performance degradation from virtual DOM object allocation overhead.
Not really. Rendering was always a heavily optimized area. The DOM, by the way, is also an in-memory data-structure, and can also be clever on how it batches draw commands to the hardware (GPU or otherwise). I was always skeptical of the performance benefits of frameworks like React for that reason.
The big benefit of UI frameworks (React or Angular) is that it organizes your code into a defined, maintainable pattern. Traditionally JavaScript has been a mess of a programming language so with raw JS/HTML development it was easy to shoot yourself in the face and do the wrong thing.
>I was under the impression that a lot of optimization was done in reaction to, err, React and similar frameworks?
That's not true. There is an enormous amount of investment being poured into the entire HTML/JS/CSS stack.
One DOM mutation is faster than one VDOM-to-DOM flow, though, of course, since the latter's doing the same thing plus more. The latter also uses a lot more memory, and keeps it around indefinitely unless you want to risk performance-killing deallocs and allocs later (I'm making some assumptions there—I'd expect a typical VDOM implementation's memory is rarely released, since re-building that data structure would be high cost if you need it again and largely defeat the purpose).
VDOM's also pure JS in the typical implementation, which is going to tend to be slower and (much) less memory efficient than getting the fuck out of JS and into the browser's C++ or Rust or whatever, ASAP (React's, for instance, is a big ol' tree of JS objects, AFAIK).
If you're often modifying or inserting 10,000 elements per update and can't be bothered to somehow batch those yourself, virtual DOM is probably a performance win. If the count is typically more like 1-10, it's probably overhead. In between, shit, I dunno, benchmark it.
My impression is that it's the kind of claim that's actually true in general, despite being false in all the particulars.
Like, every step of the way, yes, virtual DOM adds extra steps to the process, and they have a cost. But, in the big picture, if you're manually manipulating the DOM then you're liable to just swap out entire chunks of the tree rather than making surgical manipulations. Because manually managing all those surgical manipulations would quickly become a fiddly, unmaintainable mess. But, if you do it that way, you're asking the browser to do a lot more re-rendering, and that would be costly.
I worry that this conversation falls into the same trap that most performance discussions fall into, where we quickly become focused on what things would be like if people had unlimited time to chase the best-case scenario, rather than what things are like for the 99% of us who are just trying to get something that works acceptably by the next deadline.
Not using react made everything work amazingly fine. Granted this was an application with fairly low amounts of DOM manipulation (popup things when the user clicks on stuff, some lists that elements can be added/removed to/from), but those sorts of things seem fairly typical.
I wanted to use React because the code was so much cleaner and concise, but it was just way too slow.
I've been hard on React in other places in this thread because I agree with the premise of the article that VDOM is not free and that the value of React is not in performance over raw DOM manipulations, but rather in code organization.
Having said that, React isn't bad either. That it was too slow for you, I suspect, comes down how you wrote and structured your application and not necessarily React. It's been a few years since I did any meaningful React development, but back when I did, React code was simple enough that it wasn't hard to understand and trace trough, or profile. I guess I'm curious, what the bottleneck was.
Interestingly enough, this was the opposite of my experience. For my next project I used Mithril because it was far easier for me to debug, trace, and profile through.
> That it was too slow for you, I suspect, comes down how you wrote and structured your application and not necessarily React.
I had on the order of 100 inputs with two-way binding. My code was structured along the lines of the existing react tutorial of the day (maybe 10ish years ago?). Per suggestions of members of the react community, I restructured it to use ImmutableJS to allow for faster VDOM diffing, which did cause a noticeable speedup, but was still dog slow.
I agree with you in general, but I can’t agree with this statement. Web development needs fewer gatekeepers.
I don't particularly like React and I never used it, but I can see how it improves performance over naive use of browser APIs, because you can easily do things that are really bad for performance and require needless layout calculations when updating DOM manually, while tools like React will sort the updates in more optimal way without too much thinking.
As a bootcamper who came from a philosophy background to frontend, you will be surprised how many 15 year "veterans" in web dev can't write coherent code without a framework, couldn't tell you how designing data one way or another impacts their code design, and when you confront them on this, bring it to their attention, they find any which way to dismiss the problem with "do we really need that"/"why do we need that" as if their's virtue in pretending to be the Product team in the face of shoddy engineering. Enterprise agile largely enable this fairly low floor. Engineers can handwaive anything in the name of the holy right now.
> As someone who has written fiddly DOM manipulation code, no its not my preference over React JSX, but having the level of understanding TO write surgical DOM manip code should be a basic floor of ability for any web developer using react or otherwise imo.
I'm not sure I agree with this. Basically, it requires a much higher degree of experience and skill to write DOM manip well. There aren't really great resources that I've seen, because it's all very context dependent and something you learn over time. We used to send people straight into the DOM when they wanted to make a simple app, and the result was a lot of huge unmaintainable messes, security nightmares, and poor performance.
The value of React is that you can just follow the docs on reactjs.org that will give you a mediocre default. If your needs go beyond that, you can get a more skilled person to come in and improve the critical parts. The world's need for web apps outstrips the supply of highly-skilled, highly-experienced developers, so it makes sense to have libraries that lower the bar.
Turning things into JavaScript-heavy single-page applications has, I would assume, an effect of shutting out people who are good at HTML+CSS, but less so at JavaScript. I don't know how likely a profile that is nowadays because I'm buried deep deep deep in backend-type work, but it used to be fairly common to have front-end people like that who were stronger on design than programming.
Is this a form of unwitting rent-seeking behavior? Has the profession created an artificial supply-and-demand problem by convincing the managers of the world that they need expensive single-page applications built by Software Engineers™, when a (less expensive, I'm assuming) Wordpress site developed by a web designer would have sufficed?
For context on where I'm coming from: I've mostly been a back-end developer for a couple decades. I've known HTML and CSS since the '90s, of course, I'm just now starting to learn Web development in earnest, mostly as a hobby. I'm finding React's learning curve to be just incredibly steep. For the stuff I've been doing, I've had a much easier time getting acceptable (to me) results out of a more oldschool-flavored tech stack, with server-side templating and a moderate sprinkle of vanilla JS. No, it's not fancy, but I'm not looking to flex; I'm just looking to whack together a website that looks nice.
I'm not saying developers don't have an attitude problem. We often do. I just think you might be assuming malice where there might be none.
This is neither here nor there. Some people write awful React code too.
> having the level of understanding TO write surgical DOM manip code should be a basic floor of ability for any web developer
I mean, knowing how to do it is good and all, but knowing how to do it well is a rare skill. There's a ton of random performance gotchas to be aware of (like, reading a property in the middle of a bunch of writes causing double repaints) and frameworks do consistently apply optimizations that you as a regular dev would probably not ever think of (sorting optimizations being some of the least trivial ones).
"Swapping out entire chunks of the tree" is in fact a very sensible choice given that the browser rendering pipeline is highly optimized and can run in parallel, whereas any v-diffing step has to be done in single-threaded, non-native JS. You also save on the overhead of storing the vDOM itself, which will be quite significant.
How so? It improved on JQuery's performance ten-fold which was the "easy" way to webdev at the time.
I feel that way about a lot of articles like this. I want to know what you do well, I don't want to hear someone complain about something else.
Sell me on what you do well and what that means for me.
I work in React a lot and I don't feel like I run into this “pure overhead” type concept in the way they describe it and thus this article makes me:
1. Wonder what they're doing in React that they feel this way.
2. The article quickly becomes much less relevant to whatever it is I'm thinking about.
I think you're interpreting their messaging as "Svelte's compiled DOM is faster than virtual DOMs ergo Svelte is appropriate for every application" whereas the implication is certainly "Svlete's compiled DOM is faster than virtual DOMs ergo Svelte may be a good choice for applications that are constrained by virtual DOM". I don't think it's a reasoning failure, but rather a misunderstanding (an inadvertent straw man on your part).
> Svelte probably hasn’t taken over because the real world isn’t synthetic benchmarks and most apps have more significant concerns than how many times a component can update per second - and even then, in my experience React is more than capable of doing a decent job here
I think this makes a fair amount of sense. Often an incumbent needs to be quite a lot better in order to justify the learning curve, and I'm not sure that Svelte is. That said, I've been part of a lot of Python projects because Python's problems don't often manifest for new projects, but rather at scale (real workloads suffer from Python's poor performance, development velocity decreases at scale due to type annotations, package managers crawl as the dependency tree grows beyond the "toy" category, etc). I wonder if perhaps there's a similar effect in which React is "good enough" for new projects but not enough for
> The irony is that Svelte compiles code that will then run on a JIT under a JavaScript engine. That’s strictly overhead.
I don't understand this claim. In order for it to be "strictly overhead" we have to assume that Svelte's compilation step has no benefit i.e., the output code doesn't reduce the JIT's workload but even more than that, the output code has no advantages (i.e., performance advantages) over React?
> I know this article is from 2018, but it never landed well for me, and Svelte’s virtually unchanged irrelevance should be some kind of cautionary tale. I don’t think there is anything wrong with Svelte. But this isn’t how you sell a framework to programmers, in my opinion.
The way you sell a framework to programmers is largely by the backing of huge tech companies who use it in large, noteworthy projects. That's presumably not an option available to Svelte developers?
Because that is the topic of the article.
It never even says "The virtual DOM overhead is a problem". It actually says exactly the opposite, it's often fast enough and not a problem. It didn't call Virtual DOM a meme, it called "the virtual DOM is fast" a meme.
Performance wise, as the article says, it is pure overhead. Virtual DOM is the solution to a problem the javascript frameworks create themselves.
I've had argue against managers that no, using a virtual DOM will not magically make our pure JS app run any faster. Especially once I put in the work to make the DOM as seldom accessed as I could.
There is a fantastic reason these JS frameworks work that way. Instead of building creating and update logic, you just need creation logic and always rebuild the widget. But that's super slow, so you use a virtual DOM to make it faster. Just not as fast as it would have been if you hadn't used the framework.
The tradeoff being that your code is often significantly simpler and easier to maintain. Though that also breaks down in some parts.
a more catastrophic failure of reasoning, that is far more prevalent, is not understanding that virtual DOM is overhead on top of the regular DOM, not some magic fairy dust invented by facebook geniuses that just makes the web better (tm) because you are a dev whose first exposure to web development was via a React tutorial where you built some <popular app> clone as it held your hand every step of the way, and now you are loosed into the jungle of problems in the wild ready to crush the spirits of those old tired jquery devs. bwahahahaha.
Svelte performance is a nice bonus but it is the last reason I prefer Svelte over React. I prefer Svelte because it is truly reactive (unlike React) which makes everything easier, cleaner & more readable.
Svelte is the only framework you can grasp in 10min by just looking at a few examples. To get started, you don't even have to read a tutorial or documentation, the code is self-explanatory.
React is a complex beast and, in my opinion, all this is an overkill / overengineered environment for expressing UIs.
I find Svelte to be the only framework that "make sense". Ultimately UI is not that complex, it's a store -> derived variables -> UI where each step is a reactive function of the previous one. A framework should let you express this very concisely and take care of everything else for you.
If x = y + z then I want to write x = y + z, end of the story. Like in a Excel sheet, just write the formulas and that's it. No useStates, hooks, componentShouldUpdate(), and other wierd stuff.
Svelte is to React what Pluto is to Jupyter Notebooks, less popular because of legacy, but, in my opinion, obviously more elegant & cleaner
The state management in Svelte is fantastic.
Modern software commonly goes through multiple transformation (compilation stages) and it's increasingly common for some of them to be AOT, and some to be JIT, and neither AOT or JIT is overhead, even in combination. They have different pros/cons and in fact together you get the best of both worlds.
This doesn't negate your main point, but I wish you didn't end with an example of "irony" that actually is incorrect.
Secondly, you're dismissive of the idea that 'the virtual DOM is fast' is a meme (in the original Dawkinian sense; I'm not talking about gifs with Impact-typefaced captions), which suggests you haven't spent a lot of time around developers on places like Twitter and Stack Overflow. This misperception _absolutely_ exists, and this article was written to correct it, not to 'sell' Svelte.
Svelte isn't intent on 'taking over'. We're quite happy providing developers with an alternative to React that enables them to write less code and not have to worry about performance. That said, I'd argue the 'irrelevant' label is somewhat unfair (https://twitter.com/swyx/status/1409529125539254277, https://2020.stateofjs.com/en-US/technologies/front-end-fram...).
And this, ladies and gentlemen, is how we ended up with web pages that lead modern mid- and even high-end personal computers grind to a halt.
Squeezing performance out of DOM manipulation is really tricky because the performance profile of pretty much everything changes frequently without rhyme or reason.
So I'll take the dev that looks things up, as there's much more possibility they're operating on more up to date information.
Consequently, this is why I also tell people to stop repeating "this is a best practice" a year or so after something is discovered. It's a "common practice". You don't have enough info to know if it's truly "best".
The most brilliant part of Svelte was the decision to stay as close to JavaScript as possible, so anyone who knows JS, HTML, and CSS knows svelte. Importing any vanilla JS library is plug-and-play, meaning the community and ecosystem span the entire JS ecosystem. No more x-for-react or y-for-vue.
The unbeatable performance is just a plus for me. The DX is so good that building things is incredibly fun, intuitive, and headache free. I can’t emphasize enough how empowering it is.
It’s so exciting seeing the community grow exponentially lately!!
This makes me feel conflicted.
With React/Angular/Vue you're given a stable base upon which to build new components and logic, so most of the libraries end up being vaguely consistent with the underlying tech.
With JS libraries it's the wild west once again and before you know it, your components will need 3 different mechanisms of being initialized, their internals will use different approaches, before long you'll have multiple versions of jQuery in there as well and it'll make you consider the downsides of that approach.
But maybe I only have that outlook because I've witnessed many such situations of poorly integrated JS libraries and have therefore gotten used to walled gardens.
Oh you sweet summer child. Wait until you see the multilayered horror of devs insisting on styled components because they never spent the time to learn the specificity rules of CSS; their grabbing at lowdash debounce or react-virtual because they don't have the confidence to build a leaner version themselves; suggesting that core concepts of the web are outdated because they came up in the Age of React.
React/Vue/Angular will not protect you from bloated, poorly written apps. I would argue they encourage bad practices.
The number of times someone told me they prefer using Bootstrap classnames while using CSS when they bootstrap does not provide a classname for it... My front-end heart sinks!
Good on you if you prefer writing everything from scratch. Some of us have shit to do and goals to meet and we'd rather spend our time on building actual functionality than reinvent the wheel for the nth time.
Maybe less elegant or performant in some respect than pure CSS, but with trade offs that some development teams will happily take.
I also hate the sentiment, that software development needs to adhere to some notion of purity or divine elegance. And yes, I'm using the word divine because people like the grandparent comment keep acting like CSS is the church. It may well be, for some, but there's a reason why CSS is getting new features continuously... Because it's not perfect for every purpose across every development department.
Talking about this makes me sick.
But if that use case is We don't have to learn CSS because we can just not think about it with this nifty innovation then the use case is horrific.
Maybe someone just didn't have the time confidence or interest to learn CSS. Maybe it's as simple as doing what you want, doing what you can afford to do, etc.
What I don't like is the negative framing of this choice. Bad things will be built, regardless of the underlying tools. Grandparent claimed that using Frameworks results in bad practices. I claim that shaming people and questioning their choices (whether they made them consciously or unconsciously) is a bad practice.
I'm talking about people deciding to use a certain technology with tradeoffs.
You're talking about people going against quality standards of a development team. And that's where I end the conversation, you bore me.
I haven't been hostile to you or anyone who disagrees with me, by the way. Just trying to understand if and where I'm incorrect.
Furthermore, I said what I said in reaction to someone disliking the idea of Svelte being able to use any javascript library at all because of the chaos and bad practice that represents.
> You're talking about people going against quality standards of a development team.
That's what I've been taking about this whole time
Except later, maybe your project needs some custom functionality. Now you have to dig into docs to see if it's possible, then deeper into the source code to see if you can monkey patch using something undocumented. Maybe now it takes more time to cobble together what you need than wiring something lean from first principles. Understood the full import of the dependency from get.
Yeah let's stop (re-)using open source software and write everything ourselves.
Who needs React when we can have cuddlecake's spontaenously written mini-framework (I lovingly call it anguvuesveact, because I got inspired) that definitely does not provide the required feature set or developer experience to support a productive professional development process, but it's mine.
Now that we have WebAssembly, couldn't we write applications in actual Assembly? It just takes confidence that we can build something lean with it, no other considerations necessary.
Well, uh, I just realized we don't need to rely on Firefox, if we just, uh, develop our own browser, uh, from first principles. A lean one, to be sure, only providing the features we need for our Web App. If we need new features we'll build them along the way.
Ah shit, my DIY lodash (I lovingly call it cuddledash, because I got inspired) has a bug but I'm focusing on the custom browser, so no time to fix that. :/
> React/Vue/Angular will not protect you from bloated, poorly written apps.
Only our self-written lodash lib will protect us, hear hear.
If a library is maintained, the existence of a framework wrapper doesn’t make it any more reliable in my experience.
Yes! I've been a full-time React developer for about 5 years, and recently had the chance to try Svelte on a small pet project. I'd written most of the project in React and had a free weekend so I figured what the heck – let's see how it'd look in Svelte. :)
Within a day most of the functionality was in place, and the code just felt _beautiful_. I loved that it removed so much boilerplate (wrote some examples here[0]), and some of the React headaches (like using "Undo" in a controlled <textarea>) were just gone. The ergonomics (especially the built-in stores, error handling, and <svelte:head>) were lovely surprises!
I'm really bullish on it and so happy it's starting to grow.
[0]: https://react-query.tanstack.com/ [1]: https://github.com/SvelteStack/svelte-query
I think that many decisions, like creating a virtual DOM, make a lot of sense in isolation. But, if you look at the complete ecosystem, no sane human being would have ever designed anything like that.
Maybe, the Virtual DOM is pure overhead if you look at the complete system, but:
1. It was reasonable at the time 2. Some other patch to the Web Ecosystem will fix this
The more systems are interconnected, the more difficult is to change anything radically and only incremental changes are possible.
So, even if it's not necessary now, there's not necessarily any escape. The problem with complex tech stacks is that, for a variety of technical and social reasons, it's much easier to add to them than it is to take away. You can't necessarily incrementally roll back any of the bits of an existing React-based site; such an effort is liable to spiral into a complete rewrite. It's relatively easy, though, to incrementally add new things in order to paper over whatever's bugging you at the moment.
The social story is similar. Coming from a position of knowing very little, the effort for me to learn the vanilla JS way of doing things is roughly similar to the effort to learn the React way of doing things. But, if I were already invested in the React ecosystem, that wouldn't be the case. I wouldn't just have to learn new tooling, I'd also have to re-learn my entire way of thinking about how to architect a webpage. Realistically, you can't, all else being equal, justify a radical re-tooling in order to achieve an incremental benefit like that.
I'm not personally building apps, and I'm certainly not building things that need to be single-page apps. I'm building websites. They may be dynamic, they may include interactive elements on the page, but they're still mostly just plain old websites with limited state to manage. Which is fine by me. I suspect, that, were it not for those social constraints I described up above, that would be fine for most websites.
One of the other problems with complexity is that it's addictive. You get a taste of it in a situation where you actually need it, and next thing you know you're afraid to go anywhere without it, because you're worried (or is it hopeful?) that you might need it again.
"Vanilla C" maybe isn't a perfect analogy because the language and standard library are both covered by the same spec. But I suppose I would argue that it means, "Just C and its standard library, not including, for example, glibc extras." I don't know what a C equivalent to React would be. Maybe a better analogy would be "Vanilla Java", with the intent being to imply that you aren't using Spring?
"Vanilla C" doesn't have the same context as far as I'm aware. In the same spirit I could imagine a comparison for C would be along the lines of "you could use SDL (Simple DirectMedia Library) for your indie game dev, but why bother when you could use vanilla C (code Vulkan 3D graphics API directly)".
I think that the independence of various parts of the web stack is actually a strength, not a weakness. Because you don't need the complete ecosystem — you can pick and choose which parts to use, mostly without compromise.
That's just cheating though, isn't it? And not in a good way. If you smear your DOM update over consecutive frames, you can maybe cram in 2-4x more operations in there before the user starts noticing. Past this point, a smeared update starts having design implications - things that should happen simultaneously now happen sequentially. Not to mention, application starts to feel heavy.
Svelte on the other hand is as optimized as possible - update the data, modify the corresponding DOM pieces directly. There is no realistic use case where you’d need to spread an update over multiple frames.
>> I've worked on multiple modern JS frameworks and Svelte is the closest I can get to mapping my mental model of how a web page works (HTML, CSS, JS) with the framework.
Actually, I should correct myself - yes, the breakdown in terms of technology is HTML, CSS, JS but the underlying abstraction is actually - structure, presentation and functionality.
This is where, imho, Svelte really shines. It helps you to map your mental model of structure, presentation and functionality to it's corresponding implementation of HTML, CSS, JS with a sprinkle of syntactic sugar. This goes way far in keeping the code easy to understand and maintainable in my opinion.
Javascript was a meme language, but it was easy to use and highly accessible. Now its everywhere, in everything, including places it has no business being.
React has become that for frontend development. React is easier to use than Svelte. I got excited when I first learned of it, but its awkward to use at times and far more quirky than React.
As others have pointed out, that bleeding edge performance is only as great as what you are building. If you don't need to update the DOM multiple times a second, then it barely matters.
JavaScript is the wrong example. It didn't succeed on merit, but because it was the sole language available for the web platform for the entire history of the web until recently and even now it enjoys significant "unfair" advantages (browsers only expose DOM APIs to JavaScript, the JS standard library is baked into the browser while other languages must ship their own over the network, etc).
I’m curious- how much experience do you have with Svelte and what in particular do you find it makes more difficult or convoluted than React?
But of course, for complex stuffs, react's bigger community becomes to the rescue with many edge-cases solutions
I disagree. I've found Javascript to be quite complicated.
However, I agree with your takes that:
1. It's highly accessible - yes, you can learn a single language and get away with only knowing that language for a good chunk of your career nowadays.
2. It does involve fairly immediate feedback (somewhat akin to Python in that regard), because it's interpreted. Given that it's also visual, and a strong majority of people equate the internet to solely what you see in a browser, it's a pretty gratifying experience (even if, later in your career, you avoid it like the plague).
There might be other good reasons to use a VDOM (including cases like using the DOM in a web worker). But I don't think performance is one of them.
this is a no-brainer, right? The tricky part is how you identify redundant calls and eliminate them, knowing that some have more cost than others.
That will still only result in a performant, smooth 60fps application if you can do all the calls and ops that aren't redundant in less than 11ms (16.6ms per frame, but the browser needs about 5ms to update the screen). If you're trying to do more than you can calculate in 11ms then you have to start spreading things over multiple frames hopefully doing what's most important first. This is pretty much what React's concurrent rendering claims if can do for you. If it works well it really will make applications feel significantly better. As far as I know Svelte doesn't have a solution for that. It just hopes you can get everything done in that 11ms.
To be fair, 11ms is quite a lot of time on a modern computer, so unless you're doing some heavy calculation work that you can't move off the main thread to a worker you should be fine.
The diffing is mostly an implementation deatil that is abstracted away. React could check to see if props.items changed instead of the nonsense it does. If it still does that in 2021.
The thing is vue uses getters and setters that would trigger direct changes without needing to diff the entire tree. It could theoretically be really fast, but it still used a virtual dom, and it was around react speeds, give or take.
I am convinced that if react really wanted to, they could make optimizations to make it really close to svelte. I remember seeing a tweet by Evan You about vue3 being pretty much as fast svelte if not slightly faster.
The point is that speed, when it comes to front-end frameworks, is a weird thing. There are other factors that are much more important like tooling, stability, code style, dealing with animations, etc.
Things like svelte's compiler approach are much more interesting and unique selling points.
Facebook has been working for a while on Ahead-Of-Time compilation for React. Interestingly, it looks like they thought the problem was too complicated and they gave up:
> To address this challenge we initially experimented with one approach to ahead-of-time (AOT) optimization — Prepack — but ultimately that direction did not pan out. Specifically, we realized that many AOT optimizations don’t work because they either don’t have enough global knowledge or they have too little. For example, a component might be static in practice because it always receive a constant string from its parent, but the compiler can’t see that far and thinks the component is dynamic. Even when we could make optimizations work, we found that they were unpredictable to the developer. Without predictability it was hard for developers to rely on them.
Instead they're now experimenting with moving the virtual DOM resolution to the server and avoiding sending all the "templating" code to the client, which achieves a similar result. See https://reactjs.org/blog/2020/12/21/data-fetching-with-react....
> But it turns out that we can achieve a similar programming model without using virtual DOM — and that's where Svelte comes in.
Ok. I’m convinced in principle but is there a follow-on blog that describes specifically what Svelte does differently?
- smaller (because Svelte doesn't include Svelte in the binaries it outputs, but rather a dynamically generated static mapping between data and elements)
- better organised (single function components, with the JS, HTML and CSS in a single file) - like Vue!
- simpler (name = 'Joe' instead of const [getName, setName] = useState(null); setName('joe')). The last one isn't quite true as you can't use this in all circumstances - fruits.push('pear') won't update fruits, you have to run 'fruits = fruits' afterward to trigger the update (there are other ways too).
Svelte is a component framework — like React or Vue — but with an important difference. Traditional frameworks allow you to write declarative state-driven code, but there's a penalty: the browser must do extra work to convert those declarative structures into DOM operations, using techniques like that eat into your frame budget and tax the garbage collector.
Instead, Svelte runs at build time, converting your components into highly efficient imperative code that surgically updates the DOM. As a result, you're able to write ambitious applications with excellent performance characteristics.When Svelte builds your app, it’s fully aware of what components will need to update when data changes, and so it can wire up those precise dependencies statically. Then when data changes at runtime, instead of needing to diff the new state against the old state, components are updated in the way that was prescribed at build time, which is maximally efficient (as long as Svelte’s compiler is reasonably smart).
I came to realize that I had confused the reconciler. The fix is basically to just use the key= attribute everywhere, not just in arrays.
https://codepen.io/recursive/pen/XWMLWBZ
If you could point to anything in the docs that I'm missing, I'd genuinely appreciate it.
This is definitely not idiomatic react and I can't ever think of seeing this in the wild. Just render two instances. If you want the value synced then it should be a controlled component, where the locked state is passed in as a prop.
This is the kind of stuff that's difficult for me to wrap my mind around. If I have to remember to "do it this way, but not that way", that's mental overhead. Especially when it's difficult to articulate exactly under what circumstances this problem occurs.
Obviously, there are plenty of people that have no problem with it. However, my first inclinations seem to be more likely to be those that React has problems with. I'm having a difficult time "thinking in React".
As for rendering a single instance in two places, you'd see weird behaviour trying to do the same with raw DOM element instance (well not so weird as not being able to render in two places).
I don't know what to tell you, just don't do this?
I've been working professionally for years in React and have never encountered this particular issue. Once I've gotten to to it this morning with fresh eyes it's taken me like 5min to understand - React sees this as a list of the same element, which requires keys - this on the other hand is extremely common and well documented, so even a junior could intuit it.
This is a contrived example and as a moderately experienced developer you would almost certainly reach for the idiom, which would be rendering the input as a list with a map, in which case you would see clearly what's going on, get a warning, and a clear mapping to the official docs [1]
As far as footguns go, I think this is a weak and contrived example. I get why one would not want to work with React - maybe they don't like JSX, or the lack of baked-in state management, that there are a million ways to do the same thing, the general philosophy of the framework, etc.
But I've worked with many other technologies on the front and the back end and not only have I seen infinitely worse than this, I can't think of a technology where if you try really hard to break it, you won't find ways to do so.
I eventually did figure out what's going on. I did figure out that using key= solves it. I also found I could use class components and make the three labeled instances in the constructor. That gives them a long enough lifetime to stay consistent also.
I'm not trying to tell anyone else they shouldn't use react. It's great that so many find it to be so productive.
You might say I dislike the general philosophy of react. I would rather choose whether I'm using 1-way or 2-way binding than being told. I actually have come around on JSX. I think it's pretty good now.
As for being weak and contrived, I don't know what to tell you. This honestly seems like a natural way to write this. I'm a react beginner. When I ran into this, it took me some time to figure it out, but I did eventually. I suppose another part of the philosophy I don't like is entire premise of virtual DOM and reconciliation. It creates another layer of concerns the developer needs to think about. This kind of stuff should be an implementation detail. Instead, you have to remember to use an array rather than unrolling. Or just use keys everywhere. More precisely, maybe you don't need to. But I would need to.
It seems like an identity confusion issue where the VDOM diff is ambiguous, and React resolves it in the "wrong" way. Adding keys to each `LabeledInput` resolves the issue, but I'm surprised that the runtime doesn't complain when you create the inputs without keys.
I wonder if this is why the checkbox that's checked moves, but stays in the same relative position (the second checkbox in the list): https://medium.com/@ryardley/react-hooks-not-magic-just-arra... or if it's just the ambiguous VDOM diff causing that.
const inputs = isBob ? [name, confirmation, request] : [name, request]
then it complains that there's no key prop and the issue persists. This shows it's because of confused identity. In the example, it doesn't complain because it doesn't understand that {name}{confirmation}{request} is essentially an unrolled loop. {name}{confirmation}{request}
is basically a hidden render loop. If you had something like const inputs = [name, confirmation, request]
and rendered that via inputs.map() (or just {inputs}), it would have complained about the missing key prop. React can't seem identify which state belongs to which item in the "iteration".Using a conditional render like
{nameInput}
{isBob ? confirmationInput : null}
{requestInput}
seems to avoid the issue as well, without using a key prop. So yeah, beware of hidden loops.I'll grant the particular example or edge case is not available in the public docs, but it's extremely easy to intuit what is happening and relate it to the requirement of list components needing keys.
Like I replied to OP, you would be in all likelihood using arrays anyway, instead of this contrived pattern.
class App {
constructor() {
this.message = 'Hello'
this.foo = new Foo
this.show_foo = true
}
bye() {
this.message = 'Bye'
this.show_foo = false
}
}
class AppView {
view({attrs:{app}}) {
const attrs = {
onclick: (e) => app.bye(),
}
return m('div.container', [
m('h1', attrs, 'Hello!'),
(app.show_foo
? m(FooView, {foo:app.foo}),
: null),
this.render_footer(app),
])
}
render_footer(app) {
return m(…)
}
}
window.app = new App
m.mount(document.all.root, {
view: () => m(AppView, {app}))
})Not saying that Angular's banana box is ideologically superior, just that all JS frameworks have idiosyncrasies.
Neither HTML or JS on its own will do what you're describing. HTML doesn't allow binding to a data source. JS doesn't allow you to write HTML declaratively. So, people build abstractions.
If an abstraction ever became popular enough and futureproof enough, there could be a case for supporting it natively. But I don't know of anything that currently exists and does what you're describing.
<BulletedList [(DataSource)]="MyCollectionProperty" />
If someone gave me a language that looks like Lisp but with car and cdr renamed to something else, is that really making my life easier?
JSX is not HTML because it need to blend logic and HTML seamlessly. React is not static site builder, it's an app builder. If your project doesn't need this sure go ahead. Otherwise are there much better choices?
Yes, but its a template DSL for JavaScript (and TSX is one for TypeScript), not a template DSL for HTML.
Building JSX outputs JS, not HTML.
EDIT: Hmm, a few minutes later, the Marko post is blank, or not, depending on whether I'm logged it. That's... unexpected. Maybe a rate limit? The working url is https://dev.to/ryansolid/what-has-the-marko-team-been-doing-... . Too late to delete the post to leave the url clear for someone else to post. :/
[1] https://news.ycombinator.com/item?id=27676785 What Has the Marko Team Been Doing All These Years? Jun14 By Ryan Carniato of Solid, now on ebay's Marko. The interesting discussion at the end (including why Marko didn't catch on) turned up: [2] https://news.ycombinator.com/item?id=27676743 Mini apps: A web developer's exploration into mini apps — apps that are built with web technologies but that do not run in browsers.
I asked Rich Harris (author of Svelte) this: https://twitter.com/jamescuenod/status/1326747369480871941?s...
Ryan Carniato (author of Solid) makes some comparisons to Svelte here: https://dev.to/ryansolid/5-ways-solidjs-differs-from-other-j... and also here: https://github.com/solidjs/solid/blob/809fd5b8683e6f8c338961...
Sites using React or Vue all seem to be searchable using standard CTRL-F for me.
In other words it virtualizes views (like when you have a 1000 row table and you only render rows 40-50), but this is not the same as DOM virtualization.
I genuinely tried React and had to ditch it. Way too much drama just to manage state. It is clearly for building components, not applications.
I don't think comparing the two is relevant. Angular gets in your way if you are just building components but it unleashes a deluge of productivity instantly if you need to build an application--especially for a team.
I almost like ngrx because it reduces boilerplate, but I don't understand why their createAction helper doesn't follow Flux Standard Action; I can't be convinced this isn't a design flaw
https://htmx.org - server interactions in HTML
https://alpinejs.dev - small front end tweaks in your HTML
https://tailwindcss.com - styling in your HTML
This is pretty a simple stack that keeps everything in one file (for something I am calling Locality of Behavior[1]) and all of them are dependency free.
full disclosure: I am the author of htmx
Do you have a starter template with all of these hooked together? Or an example repo?
Not to be "that" guy but what you're describing is a .vue file. And with a Vue single file component you have 1 dependency: Vue. With HAT you have 3. Or am I missing something?
If I see this:
<button hx-get="/clicked">Click Me</button>
My immediate question is
* What actually executes when I click the button?
* How can I debug the code that sends the GET request?
* How can I customize the GET request and add stuff like custom headers?
In the jQuery example all of that is obvious on first glance.
I feel like complexity can't be destroyed, only moved around.
There is an hx-headers attribute to modify headers, or you can plug into the events system if need be.
htmx is extending HTML as a hypermedia and, therefore, is a very different model than most javascript-based apps today.
I am not sure if complexity can be destroyed (I'd need to have a solid definition of complexity to discuss that) but it can certainly be managed in different ways, some of which are more effective than others for certain problems. We don't do web programming in assembly for a reason.
Browser differences are mostly disappearing, they have gained some very good APIs are CSS has gained significant layout capabilities with grids and flex. So the need for libraries like jQuery for dealing with DOM differences is disappearing. New standard libraries like Intl and now Temporal make libraries like Moment obsolete.
The web is also gaining a component model with Web Components that will help you get some level of sanity when building some mildly complex reusable stuff. This is probably very good for content heavy sites, which make the majority of the web.
The other part of the web is applications running on top of the Web platform. Those still heavily benefit from frameworks. Having some amount of sanity when managing state is very much welcome. And functional programming models have proven that a declarative way of approaching UIs is much better than dealing with browser APIs imperatively.
So for some years frameworks will still be useful for certain use cases. For the others, we should be embracing Web technologies. Maybe with some light libraries like Stencil and Catalyst.
I then was looking at recommendations for building fully functional web apps, and the official recommendation was to use "Svelte Kit". I began the tutorial for that, and was surprised at how the philosophy of that framework seemed to completely contradict the core Svelte framework. It was extremely odd and unappealing, and killed my newly gained enthusiasm for Svelte.
Has anyone built full web apps without Svelte Kit (previously Sapper)?
Svelte Kit is just the equivalent of (an opinionated) Next.js, Gatsyby, or Nuxt.js framework. Those frameworks are also incredibly opinionated on purpose.
Have you built production apps with just Svelte? Is the tooling and feature set good enough to use Svelte alone in an actual app?
What did you find unappealing about Kit?
[0]: https://www.reddit.com/r/sveltejs/comments/ni9g5d/svelte_vs_...
Do you have concerns with using SvelteKit in production? It's still in Beta last I checked.
That said, I think the replies covered the concern pretty well. For me, I don't really have any concerns with it. I don't find it very opinionated nor restrictive, but I come from a Rails background where I'm used to convention over configuration, so maybe I'm biased towards reasonable defaults.
> DOM mutations are not the expensive thing, it's the final render.
This is the crux of the issue: Updating the DOM will immediately rerender the page, even if there are additional changes that need to be made at the same time. So library/framework authors twist themselves into pretzels trying to work around the browser automatically doing all this unnecessary extra work that developers don't even want. Clearly it's a DOM api deficiency; there is no api to 'make these 15 changes scattered across the DOM all at once', instead each individual change causes a cascade of wasted effort repeated until the last change is applied OR developers take the nuclear option and just replace the whole damn page with a completely new DOM on every frame. Insanity. The solution seems obvious to me:
Browsers should introduce a transactional DOM api that is only rendered after the transaction is 'committed'. It could be full-on transactions like a real DB or something simpler like a double-buffered frame swap. This would be relatively easy to retrofit into JS apps and frameworks and would enable them to effortlessly avoid a huge amount of wasted effort on the part of the browser.
I eventually built a VDOM-based frontend WASM framework in Rust (Seed).
I now built frontends in HTML and CS, with no frameworks, and minimal, targeted JS code to manipulate the DOM directly; it's liberating, and much faster than both React and WASM/Rust.
Sigh. https://wiki.gnome.org/Projects/Seed
(JavaScript-related, so not just any random name collision.)
I also found it pretty comical when server side rendering became a hot topic, like duh guys, that's what we were doing first! Did you forget?
Anyway, it's not that frontend UI frameworks are bad, it's more that pragmatism gets thrown out the window so quickly.
A lot of new kids (we call them frontend engineers) haven't done the old school way. They just know SPAs, because that's what they've been taught in the last decade or so.
A VDOM tree represents far more DOM states than a template will ever be put in, so materializing VDOM and diffing are absolutely pure overhead compared to the system knowing ahead of time what might change. With VDOM you repeatedly compare many nodes that will never show a diff, and that's just waste.
VDOM brought three important things to the table, initially paid for by that overhead: * Template as values. JSX expressions produce JS values, and this is allows a functional programming approach to UI. * Expressions and control flow in JS. This shrunk the domain of the template DSL to just the component nodes, and reused knowledge and machinery of JS. Theoretically that leads to faster and smaller templating. * One-way data flow. This is a result of the first two items, but important on its own. Two way binding is nice sugar for some situations, but it makes it hard to reason about the state a template is in.
Those are really great aspects of the VDOM approach (for a class of programmers, markup based templates are great for others).
So the challenge to me had been to preserve those features, actually deliver on the smaller and faster part, and reduce the CPU overhead. That can be done with compiler-first systems like Svelte, but I think we get just as faster or faster, and as small or smaller with a pure runtime approach based on template literals, like we have with lit-html.
Template literals let us describe the static and dynamic parts of a template separately, so there's no VDOM overhead. We don't compare the output of template expressions, we compare the inputs to the dynamic bindings. It's often an order-of-magnitude less diffing work, and approaches the point where the required DOM operations are the limiting factor. So we get low-CPU overhead, templates as expressions, logic in JS, and one-way-bindings, with no compiler. I really think this is the best of both conceptual simplicity and overhead - preserving much of the VDOM model, but doing it faster.
I think this approach definitely has a lot of merit, but in terms of absolutes, it's still not quite there. Specifically, you're still going to be diffing as many bindings as a component has, be it one or one hundred, even if only one changed.
Another more micro-level issue is that dynamically resolving which DOM properties to update is polymorphic, so you don't get nearly as much JIT optimization compared to a compiled approach that outputs monomorphic static property assignments.
I quite like Solid.js' approach, which addresses both of these problems via a reactive data flow and aggressive compilation, while still providing a React-like experience.
> It's important to understand that virtual DOM isn't a feature. It's a means to an end, the end being declarative, state-driven UI development.
Declarative, state-driven UI development is a valuable abstraction.
I really hope readers take this to heart, rather than the article title becoming a new meme.
> it turns out that we can achieve a similar programming model without using virtual DOM — and that's where Svelte comes in
The abstraction is valuable, but its cost need not be so high. I do wish they'd elaborate on what Svelte does differently though, or link to another post which elaborates.
The "Rethinking" post gives a little more detail:
> Instead, Svelte runs at build time, converting your components into highly efficient imperative code that surgically updates the DOM. As a result, you're able to write ambitious applications with excellent performance characteristics.
https://svelte.dev/blog/svelte-3-rethinking-reactivity
Seems like a great idea, if it can gain the critical mass required and build a community of people developing code for it.
Which browsers do not support natively for decades and entire markets of ecosystems grow to work around that stupidest fact. Browsers could detect, batch and “reconcile” (whatever that means) the changes to the js runtime with much less runtime and devtime overhead than it is done in js by manual state tracking and updates.
Actually, is anyone else doing it the Svelte way?
It appears MoonZoon uses https://github.com/Pauan/rust-dominator which, like Sycamore, is also a DOM library that doesn't use vdom.
More so than I would typically see in any other ecosystem. But nobody seems to care. Is is that it makes for a sort of meritocracy where people that keep up with the fast changing landscape get the best opportunities? Basically, I can't figure out why JS developers aren't overwhelmed and frustrated with all the choices.
- The Angular dependency injection stuff seemed rather complicated compared with React pragmatism. Using React became heavier by the time Redux and other boilerplatish practices became widespread, but React had already gained adoption by then, and you could still get into it on tiny projects without fancy state management.
- The VDOM had articles saying how much faster it was than everything else, so it gained a reputation for speed compared with the other client-side templating alternatives at the time. Angular 1 had a reputation for being slow due to scanning all state variables on every refresh. Really React wasn't fast at everything, but fast at enough things to get that reputation. People who really understood DOM differential updates already knew how to do it faster than VDOM, either by hand or with smarter differential template compilers, but implementations weren't common. Marko and Svelte came along later.
- After years of being trained that separating HTML templates and code was the right thing to do for better engineering, preferably in separate files, it turns out that was annoying and lots of people really liked inlining the dynamic parts of HTML directly into code.
I ask in complete earnest, and if I should just be reading some particular Wikipedia article I'm grateful for any links.
Sometimes, I'd make use of a component that did this itself, but yeah. At least back then, it was a lot of manual wiring. Maybe similar to backbonejs in some ways.
The toy video games that I wrote were more React-like, in that you would simply update your models, and then a separate process would re-render 30-60 times per second. So, as a developer, you could really just think in terms of data transformations.
Anyway, it's been 15 years since I've done either. I'm not sure how modern, native toolkits work. I assume there are decent React-like top-down-dataflow approaches these days.
I personally love the idea of the VDOM, because it liberates the content from being stuck to one document type: HyperText. While true when VDOM showed up on the scene, Facebook and others said the VDOM would help cure performance issues and that was the main selling point.. as we see now with things like ReactPixi, and Netflix using React for some of their apps - the VDOM is infinitely valuable for transcending the limits of HyperText and instead abstracting it away so that content may be projected by any sort of renderer using the same scaffolding as web pages. If you code to just the DOM - that is is where you will stay. Forever.
Svelte native exists…
The VDOM which mirrors the document DOM is an implementation detail of React, as something sitting between the actual DOM, and the VDOM fragment returned by a React view. It’s true that if the document DOM gets fast enough, the mirroring VDOM could go away, but some diffing algorithm would still have to reconcile the document DOM with whatever fragment is returned from a view.
I think one of the realisations of Svelte is that rather than returning arbitrary runtime generated DOM fragments from views, it is better to have the view implemented by a template that a compiler can understand and manipulate at compile-time. Here we trade off some expressivity (run-time generated DOM) for the ability to do much much more at compile time - I think this is the real point that should be being made in the article.
That true, but that points more towards Svelte taking over.
One of the big selling points of react was you could basically write your app that way and it would fine.
But what would be a minimal as possible example for this?
I know a bit reactjs and it can get complicated as well with multiform s and various elements states depending on each other quickly too.
A bad architecture can be "achieved" by either, I am curious about some examples showing me what people mean exactly by that.
(I wonder what happened to Featherstitch.)
[1]: https://lwn.net/Articles/354861/
It's a common pattern that you have a list of items of work to be done which in principle you could know ahead of time, but in practice it's better to track at runtime (even though it means the computer ends up repeating the same calculation again and again).
I still think web would be best if you do SSR and then replace HTML DOM elements using frameworks like Stimulus Reflex or Hotwire. For millisecond interactivity you may want to write JS in a framework like Stimulus JS is good enough. Personally I do not see why everyone wants to build a Single Page App when 80% of your pages are static and can be server rendered and with SSR frameworks you can build something a lot faster than building a Frontend and Backend separately and fragmenting or hiring extra developers when it is not needed.
DHH said your code reflect your org structure and I agree companies that use SPA and Backends micro service arch usually tend to require more developers rather than companies that use SSR monoliths which appeal to smaller 1-3 developer companies that are building out a POC before committing huge amount of venture capital or their own money behind an idea that may not succeed.
For 90-95% of applications, a single page app architecture with a front-end JavaScript framework running a bunch of application code and rendering output is overkill and you could write the same app in half the time using server side rendering.
I can use HTML/CSS/JS skills (and Angular) to build a serious business application that runs anywhere and looks the same on each platform (or morphs to the platform UI if I care about that).
they say they dislike complexity
but look at what they do
not at what they say
is it for fear of appearing insufficiently intelligent?
It'd be handy to have it as a flippable switch
Plain-JS DOM manipulation code can become quite complex very fast, and I think that's what opens the door for inefficiency and also a lot of errors, because it's hard to keep track of possible DOM permutations.
I would even make the same argument for JSX itself. Once again JS now have template literals built into it.
For anyone coming from a React background check out this code lab to see the difference: https://codelabs.developers.google.com/codelabs/lit-2-for-re...
In my experience it has never, ever been the JS rendering layer which has caused unresponsiveness in an application. It's almost always some type of network communication issue, be it the database stalling or static assets not being served. Where JS rendering might be a problem is at Facebook SPA scale, and the vast majority of apps are not Facebook.
I am currently working with low-latency audio and the latency requirements mean I have minimal buffering. While the VDOM render cycle is generally fast enough to be unnoticeable to the user, it stalls the audio buffering just enough to cause some stalling. There's a few heavier parts of the application where the rendering is expensive enough to briefly stall animations as well.
While both of these issues are something we need to fix, it is specifically the rendering/vdom process that we need to work around to address these performance concerns, and we are definitely not at all Facebook.
Svelte (and some other contenders, like concurrent mode React) improve performance enough that interactive animated datavis stuff can also be done declaratively.
Implemented a undo/redo stack on top of Vuex once that worked on some very large data structures.
Got unresponsiveness after only ~3 changes to the data. Purely due to how Vuex checks state for changes. No network, no database; purely in the frontend client.
Ended up needing to freeze the state as I pushed it into the Vuex store, so Vuex wouldn't check previously pushed state for changes.
My point is, there are multiple places where, if you are building an app of scale, you can run into client performance issues.
For example, you can't just create and keep a copy of a dataset / variable. It will remain reactive. You need to clone it. Failing to do so will indeed quickly clog up... everything :D
`Object.freeze` is what I used. This causes Vuex to not traverse the object for changes. in my case, the objects I was pushing into the Vuex state were essentially immutable once I pushed them in, so this did the ticket.
well, that, and only pushing partials of the entire state, so the object model didn't get too unwieldy. To get the total state, i just replayed the changes on top of the base state. base state was reset once the number of changes got to a certain size.
If I'm building a desktop app that will run in the browser then it isn't much of an issue, but if that same app is expected to run on a mobile device then my wild JavaScript kludges start to really matter.
I have in my head a few dozen examples of what I mean, some small and some large. I won't even get into TCP/UDP which has already been argued over a thousand times. But I would point to RINA and other paradigms of remote execution:
https://en.wikipedia.org/wiki/Recursive_Internetwork_Archite...
But that's the large scale stuff. We can also focus on very minor stuff where a different design decision might have lead to less trouble. Take, for instance, a mouseclick. Which element on a Web page should receive that mouseclick? Well, there is a well-established hierarchy that the browsers respect, walking up the DOM, checking each element to see if it has a handler registered. It can be a royal pain if your application needs you to break out of that hierarchy, and you can end up with something buggy because this is still an area where the different browsers have slight differences. But why should any hierarchy exist by default? We could have it such that there is no hierarchy by default, the only hierarchy is that which is defined by me, the programmer. I believe this original decision (of a default hierarchy) was made because there was an assumption, in the 1990s, that each page would be hand-coded, but nowadays we have frameworks that write much of our Javascript for us, so the possibility of assigning mouseclick handlers on the basis of classes, rather than the DOM, seems like a smart choice now, but probably didn't in the 1990s.
I tried to write about some of this in essays like "The problem with HTML":
http://www.smashcompany.com/technology/the-problem-with-html
and also, "HTML is the failed GUI for TCP/IP":
http://www.smashcompany.com/technology/html-is-the-failed-gu...
I'm not sure I really communicated myself very well previously, but perhaps if I focus on it, I can build the case that we've been following a path into a dark wood, and we've been so busy focusing on the path one step before us that we have perhaps not noticed that we've wandered into the lands where, in innocent days of yore, developers would have warned, "There be dragons, do not go."
This article avoids the fact that declarative programming has proven to be more pleasant for most people. And React simply is fast enough for most use cases, even though it has a performance penalty compared to Svelte. The virtual DOM is an elegant optimisation that usually works well in the real world, and methods like `shouldComponentUpdate()` can be used in the 1% of cases where the default is not fast enough.
No it doesn't. Second-to-last paragraph:
"It's important to understand that virtual DOM isn't a feature. It's a means to an end, the end being declarative, state-driven UI development. 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."
There's many good reasons to use React - mainly the React ecosystem - but simplicity is not one of them.
I have heard that claim myself before.
But what I really, really like about Svelte is how refined the experience is. I think that's just a natural progression though. React got invented, then it got clear that some things have to be done again and again (boilerplate code) and some parts of it are too complex. Things you can only notice in hindsight. Then Vue came along and fixed a lot of these issues (making it beginner friendlier and simpler). And now we have svelte which takes the learnings and hindsight of Vue and what React did in the meantime and improves upon them.
When projects grow, there is always this point where you have to start fighting the framework. The magic functions and implicit behaviour that makes them so easy to start with suddenly don't work for a use-case anymore and you have to almost hack a solution within the confines of the framework. Svelte on the other hand seems to be a lot more hands-off, a lot more vanilla javascript, where so far I didn't have the feeling I needed to fight it, even for ideas that were a lot more out of the box.
I started using Vue when it was there where Svelte is now, so I'm fairly confident the tooling and larger community support will be a lot better in 1 to 2 years ^^