10 ms·
I think this article - and many of the comments on this thread are forgetting the context of how DOM manipulation was typically done when the virtual DOM approa
by oraphalous 7y ago
I think this article - and many of the comments on this thread are forgetting the context of how DOM manipulation was typically done when the virtual DOM approach was introduced.
Here's the gist of how folks would often update an element. You'd subscribe to events on the root element of your component. And if your component is of any complexity at all - first thing you'd probably do is ask jQuery to go find any child elements that need updating - inspecting the DOM in various ways so as to determine the component's current state.
If your component needed to affect components higher up, or sibling to the current instance - then your application is often doing a search of the DOM to find the nodes.. and yes if you architect things well then you could avoid a lot of these - but let's face it, front end developers weren't typically renown for their application architecture skills.
In short - the DOM was often used to store state. And this just isn't a very efficient approach.
This is what I understood the claim that VDOMs are faster than the real DOM meant - and the article is pretty much eliding this detail.
As far as I'm aware React and its VDOM approach was the framework that deserves the credit for changing the culture of how we thought about state management on the frontend. That newer frameworks have been able to build upon this core insight - in ways that are even more efficient than the VDOM approach is great - but they should pay homage to that original insight and change in perspective React made possible.
I feel this article and many of the comments here so far - fail to do that - and worse, seem to be trying to present React's claim of the VDOM faster than the DOM as some kind of toddler mistake.
- toasterlovin 7y agoNot really a JS developer, but from my recollection, everything you said is essentially correct. I was on the periphery of the Ember community when React dropped. I remember a blog post or something where the Ember developers basically acknowledged that React's virtual DOM approach was significantly more performant than what Ember was doing and, to the Ember community's credit, resolved to re-architect their view rendering layer to shrink the performance gap.
- karmelapple 7y agoThat is indeed what happened, and Ember got some major performance enhancements as a result! Things like Glimmer were a result of this.
- Chris_Newton 7y agoIn short - the DOM was often used to store state. And this just isn't a very efficient approach. By some people, sure, but separating state and business logic from presentation and rendering logic was a well-known idea many, many years before React was around. I think the basic premise of the article here is correct. The important development with React that hadn’t previously been widely seen in front-end, JS-based web development wasn’t the virtual DOM, it was the declarative description of the rendered content — building it in absolute terms from the current state, not in relative terms from the current and previous state. The virtual DOM is a means to that end: it makes that approach fast enough that it can be used with acceptable performance for a lot of realistic applications. This doesn’t change the fact that the declare-and-diff strategy is extremely expensive compared to actively observing only necessary changes in the underlying state and making only necessary local updates in the (real) DOM. In a typical web app, if there is such a thing, that might not matter very much. In more demanding cases, say when you’ve got tables with thousands of cells or you’re drawing a complicated diagram with SVG, it’s still all too easy to run into performance lag with any library that uses this strategy. Then you start using escape hatches like shouldComponentUpdate or using lifecycle methods to manipulate the (real) DOM directly rather than rendering through React, at which point you’re not really benefitting from React at all for that particular component (though of course you might still be benefitting from it for the other 90% of your UI code and incorporating the rest into the same overall design using those escape hatches might make sense in that situation).
- oraphalous 7y ago>By some people, sure, but separating state and business logic from presentation and rendering logic was a well-known idea many, many years before React was around. My claim is that this isn't a good representation of the FE culture as a whole - even if there were islands of enlightment out there. Hell, just about all of the enterprise codebases I get contracted to work on are STILL do state management the old way. So no - I don't agree the basic premise of the article is correct. >The important development with React that hadn’t previously been widely seen in front-end, JS-based web development wasn’t the virtual DOM, it was the declarative description of the rendered content — building it in absolute terms from the current state, not in relative terms from the current and previous state. You are ignoring that fact that the VDOM was the imperative implementation they used under the hood to make the declarative api work. It's the VDOM that allowed them to take state management out of the DOM - and thus why they claimed that the VDOM was faster than the DOM. Sure - if other folks are finding other implementation approaches that allow one to keep state out of the DOM in even better ways - that's great. That doesn't mean it wasn't reasonable at the time to identify the VDOM with that central innovation since there wasn't many other people doing it in other ways. >This doesn’t change the fact that the declare-and-diff strategy is extremely expensive compared to actively observing only necessary changes in the underlying state and making only necessary local updates in the (real) DOM. I'm not arguing this case one way or another... I don't claim to know. The OP is certainly welcome by me to try to continue making that case. I think that's a good contribution to make. I'm saying that OP could do this without crapping all over React's contribution - which tbh honest smells like a status move in order to obtain more market share. Wanting more market share is fine - but it should be enough to just compare the performance between the two to make that case. Don't straw man a "meme" to attack a competitor's status.
- addicted 7y agoThis is how I remember things as well. The Virtual DOM was a huge improvement compared to other contemporary frameworks because it consolidated multiple changes into a single DOM operation. For one thing, all the frameworks at the time we’re doing 2 way bindings. Which meant that the smallest change could end up triggering a bunch of computeds and observables, to the point where any change would trigger a bunch of re renders. React bundled all of those into a single rerender. Further, and I may be mistaken about this, react helped dispel 2 way binding and show that 2 way binding was a performance and reasoning disaster. If that was the case, I’d suppose eliminatin g 2 way binding also likely played a large role in the performance improvements which may potentially have been incorrectly attributed to the VDom.
- concerned_user 7y agoTo me it was not only that as I didn't do games or highly interactive UI's where DOM updates would really matter but it freed me from the burden of ad-hoc updating with jquery as everybody was used to. Unless you had some framework or had invented ways to centrally store state chances are your code was all over the place. I tried 2-way binding in ExtJS and it seemed to work well at first then I started adding more and more binds to the component and at certain point performance just tanked. And it was after I started with React already so I just didn't bother to investigate, issue actually was some kind of loop being formed and things aborting due to hitting limits. Which I guess means I used it somewhat incorrectly but I never had that issue with react.
- finchisko 7y agoWell written. From my memory I remember situations trying to isolate cascade of rerenderes in backbonejs caused by multiple isolated event handlers. Also state used to problems, before state management libraries existed. And actually messenger (built in) was first app that was written in react, because it was plagued by several bugs, like not showing/resetting unread message count correctly...
- hn_throwaway_99 7y ago> This is what I understood the claim that VDOMs are faster than the real DOM meant - and the article is pretty much eliding this detail. I disagree with this. I think the major key insight and innovation with React, which this article fully acknowledges, is that it is much easier to think about declarative UI as solely a function of the current state without having to think about the transitions to arrive at that state, and, importantly, the virtual DOM lets you do that performantly. In other words, to take the example from the article, it would be great if we could have an "onEveryStateChange() { document.body.innerHTML = renderMyApp(); }" function, but doing that would be much too slow because it would recreate the full, real DOM. Using the virtual DOM lets you write essentially the same code, but in a performant manner, and I think the article is clear on this fact. I'm not familiar with Svelte, but the article has peaked my interest because it is making it sound like it lets you write declarative UI but without needing to do the full virtual DOM diffing.
- oraphalous 7y agoSee my reply to Chris_Newton's earlier response to my comment. :)
- floatboth 7y agolit-html also lets you write declarative UI without diffing (and use actual HTML tag syntax without any build tools): https://lit-html.polymer-project.org https://lit-html.polymer-project.org and LitElement gives you a base class for Custom Elements that uses lit-html with Shadow DOM: https://lit-element.polymer-project.org https://lit-element.polymer-project.org
- ben509 7y agoSvelte is a compiler, so I think it's figuring out the possible state changes as part of compilation. Contrast with React where any component can return any elements at any time.
- EB66 7y agoWhat I think this article does very well is rebut the myth that the DOM is slow. The DOM is not slow -- on the contrary, it is very fast. What is slow is browser reflow, page refreshes, display calculations, etc. In web app development of yesteryear, browser reflow was typically triggered by poorly conceived manual DOM manipulations -- which gave birth to the myth that the DOM itself is slow. Implementing a virtual DOM and VDOM diffing is just one way to manipulate the DOM more efficiently and intelligently. At my work, we've chosen a different path without the overhead and leaky abstraction of a virtual DOM. We built our own component-based SPA framework and recently open sourced it ( https://github.com/ElliotNB/nimbly https://github.com/ElliotNB/nimbly ). Each component must have a definition of what state mutations should trigger what portions of the component DOM (via CSS selectors) to refresh. There's no extra overhead for a VDOM and VDOM diffing at all. The only overhead is accrued ahead of time by the developers who must write a definition of how their component should update in response to state changes. When state does change, the framework bundles up the queued DOM changes between all components on the page, identifies/eliminates any redundant changes and refreshes the DOM in one go.
- deleted 7y ago[deleted]
- mruniverse 7y ago> ...seem to be trying to present React's claim of the VDOM faster than the DOM as some kind of toddler mistake. It wasn't a toddler mistake, but it was repeated over and over to convince people to move to React.
- jasonkester 7y agothe DOM was often used to store state. Every once in a while I'm reminded that I'm mostly disconnected from the way "most" people build things. Thanks for this insight. It finally explains why I hear people talking down about "jQuery developers", if that was something that people actually did. But wow. I've been building javascript-heavy web stuff since the mid 90's and it had never occurred to me to do that. You have your object model, and each thing had a reference back to its DOM node and some methods to update itself if necessary. All jQuery did was make it less typing to initially grab the DOM node (or create it), and give you some shorthand for setting classes on them. It also explains why people liked React, which has always seemed completely overcomplicated to me, but which probably simplified things a lot if you didn't ever have a proper place to keep your data model. I can't imagine I was the only one who had things figured out back then, though. The idea you're talking about sounds pretty terrible.
- cryptica 7y agocomplexity also kept me away from React. The main reason that it got popular is because it's by Facebook and they know how to manipulate people to use certain products over others (that's their entire business). There have always been simpler and cleaner alternatives. If React was not by Facebook, it would not have gotten popular at all except as a 'cool hack/experiment' - Nobody would have seriously tried to incorporate it into a production application. As soon as you scratch the surface, you understand that it's one of those tools that tries to take away complexity by adding complexity on top. The story has gotten more complicated though because now React has so many components and there is all this conveninent tooling and boilerplate around it but still I would never choose it over VueJS. Anything that comes out of Facebook is just pure manipulation.
- sam0x17 7y agoConvenience is to be taken with a grain of salt, though. In the node.js world, "is-odd" can be a package, and it can have 926,000 weekly downloads and 22 dependents.
- 7y ago
- austincheney 7y ago> was typically done when the virtual DOM approach was introduced. Don't care and I am guessing you didn't read the article. Ignorance of the DOM does not redefine what it is. This is just as true for jQuery stupidity as it is for React virtual DOM nonsense. Fortunately, the DOM is defined in a standard specification so there is a document of truth that you can go read. > In short - the DOM was often used to store state. And this just isn't a very efficient approach. Again, don't care. Other people's misuse and stupidity is their problem. That stupidity does not alter the technology specification. If you really want to know what the DOM is I wrote a very brief summary with links to the specifications: https://prettydiff.com/2/guide/unrelated_dom.xhtml https://prettydiff.com/2/guide/unrelated_dom.xhtml
- delusional 7y agoI still do some old school JQuery manipulations, and a lot of what kills you on the performance front is also the repeated manipulations of the same set of elements in the same frame. Often, you go in and change an element. Only to have another piece of javascript change it again. Each of those modifications then require a complete relayout of the page, that's when it gets expensive. You could say that we should just optimize our JQuery, and you'd be right. We just don't have structured way of figuring out everything that touches a "component". (What is a component anyway, when it's all adhoc).
- hopsoft 7y ago> the DOM was often used to store state. And this just isn't a very efficient approach. StimulusJS is a modern approach that uses the DOM to manage state. In my experience it has proven to be quite simple and performant. https://stimulusjs.org/handbook/managing-state https://stimulusjs.org/handbook/managing-state
- acdha 7y ago> yes if you architect things well then you could avoid a lot of these - but let's face it, front end developers weren't typically renown for their application architecture skills. … This is what I understood the claim that VDOMs are faster than the real DOM meant - and the article is pretty much eliding this detail. I agree that a large part of the problem is the lack of proper architecture and general poor quality of practice but that’s also a problem for the distinction which you’re attempting to draw. I think the core React team likely meant what you meant but the community’s love of both fads and crapping on whatever isn’t new and shiny meant that nuance was deeply buried under the “it’s go-faster magic from Facebook!!!” marketing train. I remember having absolutely surreal experiences where it was like “why are you saying it’s faster? Here’s a benchmark showing it’s 5 orders of magnitude slower.” “It uses a virtual DOM” “I know, but don’t you have a benchmark where it’s actually faster?” “You just don’t get it”. I do think React helped bring some improvements around architecture but I think an under-appreciated part of that was that since it required a full compiler toolchain, 100% of projects could use the latest JavaScript features (notably ES6 classes and arrow functions), data structures, modules rather than rewriting everything, etc. which noticeably reduced the number of complex things people had to get right, tune, and reason about.
- ljm 7y agoI love how many people there are in this thread that somehow avoided the jQuery hell a lot of us battled against. I was involved in that, mostly from when my paycheque involved throwing together websites in Drupal 6. Holding that architecture together was trouble enough without having to also care about the frontend, we were only scripting it. The idea of the HTML being considered an 'app' was utterly alien to me and my colleagues at that time. I fondly remember the short period of time where we had post after post attempting to explain what a closure is, because for most of the authors back then the concept of a function pulling outside variables into its scope was utterly alien to us. Even now this practical meme persists[0]. Ten years later and I find closures more intuitive than half the stuff we've concocted in OOP land. More than that, jQuery was a means to an end and to shove low-effort animation and UI into an app to make it look snazzy and 'Web 2.0' like (glass effect banners, drop shadows and all). If it wasn't jQuery it was script.aculo.us. Then we got Backbone and Coffeescript at around the same time, by which time I was a Ruby dev. Backbone contributed to a fundamental shift in how we build a frontend, and we had Knockout, Sencha, ExtJS, etc. following along. And then the concept of 'comet' (keeping an HTTP connection alive for long polling) and MeteorJS. The impact of React and its concept of the VDOM has been phenomenal. It may be overhead as the Svelte authors say, but the experience of working with React, and any similar library in the ecosystem, is a boon to anyone who wants to do serious work in the browser. Without being hyperbolic this feels like the legacy of smalltalk: programming in a dynamic environment, only you're not actually aware that you are. There has to be a fantastic retrospective on the progression of JS since that initial ten-day genesis. [0] https://medium.com/dailyjs/i-never-understood-javascript-closures-9663703368e8 https://medium.com/dailyjs/i-never-understood-javascript-clo...
- Klonoar 7y agoNot just jQuery... we had some crazy times with Dojo, MooTools, and so on. Closures and "this" being screwy (IMO) led to junior developers spending an insane amount of effort shoving things into DOM elements because it was a free global store that you could inspect and work with. The VDOM is cool, but React (& co's) appeal is the streamlined development tooling, approaches, and ecosystem where there's a mostly agreed upon way to do things. >I fondly remember the short period of time where we had post after post attempting to explain what a closure is, because for most of the authors back then the concept of a function pulling outside variables into its scope was utterly alien to us. Even now this practical meme persists[0]. My favorite was actually when we needed a groundswell movement to make people realize that $() wasn't a variable, but a function call, and for complex selectors (before querySelectorAll, when Sizzle was a far more complex beast) you really wanted to cache it. Or, getting people to stop attaching event handlers to every row in a 10k row table, and to just match the click to the row once. It really does feel like people have forgotten just how rough the gap was back then. For real though. I feel comfortable building something in VanillaJS... e.g, building up a fragment before shoving it into the DOM, architecting how updates are applied, etc. This is all stuff that was hard learned, and became easier the more I stepped outside JS later on. I would in no way want a junior trying to do this without learning the better practices found in React - _not_ because they need the crutch, but because I learned those some lifecycle methods and such from Cocoa/UIKit and you need a frame of reference to internalize it all.
- edem 7y agoReact has nothing to do with this. They just took an idea as old as Windows 1.0 and applied it to web development.
- stolsvik 7y agoWhy don't the credit of "changing the culture of how we thought about state management on the frontend" go to AngularJS? At least Angular is what changed it for me, and it is the oldest of them.
- Klonoar 7y agoBecause Angular wasn't the first? Angular 1.0 also left an eternally bad taste in many peoples mouths.
- jkoudys 7y agoAbsolutely, and it ignores that React has never been designed purely to render into the browser DOM as defined by the w3. The browser's DOM is simply one target, though certainly the most popular one. I use React every day for building other things: xml targets like PDFs, word docs, and SVGs, raw strings, canvases, native, etc. Far from a toddler's mistake, the team was well aware of this from the start, and the shift from everything in the 'react' package to splitting out 'react-dom' is clear evidence of this. Components are a very powerful concept that goes way beyond the common scenario of building a web page and updating it with some data.