10 ms·
Virtual DOM in Elm
- pestaa 12y agoElm looks extremely promising to me. However, I tried the Elm's implementation of TodoMVC here: http://evancz.github.io/TodoFRP/ http://evancz.github.io/TodoFRP/ and got an unusable list of strings with basically none of the features seen in other prototypes. Is it the one used in these benchmarks? What results would we see in an identical test? Update: the benchmark uses a correct implementation available here: https://github.com/evancz/todomvc-perf-comparison/tree/master/todomvc/elm https://github.com/evancz/todomvc-perf-comparison/tree/maste... so it was a false alarm on my part. Tried it out at https://rawgit.com/evancz/todomvc-perf-comparison/master/todomvc/elm/index.html https://rawgit.com/evancz/todomvc-perf-comparison/master/tod...
- mmcnickle 12y agoI think this is the version they were referring to: http://evancz.github.io/elm-todomvc/ http://evancz.github.io/elm-todomvc/
- michaelbjames 12y agoI think you may have gone to the wrong address. The second link in the article is the most recent implementation (using a virtual DOM) http://evancz.github.io/elm-todomvc/ http://evancz.github.io/elm-todomvc/
- quarterto 12y agoI assume it was http://evancz.github.io/elm-todomvc/ http://evancz.github.io/elm-todomvc/, which is more recently updated and seems identical to the other TodoMVC demos.
- jlongster 12y agoThis technique may be the most revolutionary thing in web development in the last several years, IMHO. I've been using React for a while, and starting to integrate Mori for persistent data structures, and the things I can do with it is insane. The fact that it's not only far better performant, but a way better abstraction for dealing with UIs, is crazy.
- smizell 12y agoDo you have any code samples online of this combination? I'd be interested to see how these are used together, because they seem like a great fit.
- jlongster 12y agoNot yet, I've been dying to dig into this for months but now just getting some time to do so. I'm rewriting my blog with lots of cool technologies like this and going to open-source it and write up about it. http://jlongster.com/ http://jlongster.com/
- smizell 12y agoCool, I'll keep an eye out. Any reason to use React+Mori over Om other than more familiarity with JavaScript??
- jlongster 12y agoThere is a huge amount of JavaScript developers that can't jump to ClojureScript. I love CLJS, but I have a heart for the amount of JS projects out there that can't take advantage of these techniques. It's really important that we borrow from good research and make it available to JS so that existing projects can begin integrating them, because most of them will not jump to a completely different language.
- STRML 12y agoJust wanted to add my support with this - I am using React+Fluxxor+ampersand-collections, and I find myself simply rebuilding the collections on every change (and disabling their add/remove/set/reset functions) to keep them immutable and speed `shouldComponentUpdate`, but I would rather be using mori. When you use something like mori, but you need to define data transforms, such as float precision, derived attributes, and so on, how do you make that work well in your apps without too much complexity in your components? One thing I really enjoy about ampersand-state and ampersand-collection (forks of Backbone) is that I can define very simple, standard functions per model so that my views don't have to have any idea what was passed to them. How would that be possible in Mori? Do you use something like a `__type` attribute so an external utility can suss out what the object is and transform it correctly?
- colinramsay 12y agoMy first thought when looking at the benchmarks is that I find it strange that Backbone is faster than React. Not that I imagine Backbone to be slow, particularly, just that this article is about one of React's key features - the virtual DOM - and that's something which Backbone doesn't have. I'd expect to see React up there with Om, Mercury & Elm. I've just had a look at the code and React is using a localstorage backend, while Backbone is using its models + collections with a localstorage extension... so I'd expect there to at least be some overhead there, but apparently not. Does anyone have any quick thoughts on what might be happening here? I can't shake the feeling that these benchmarks might not be terribly useful.
- pestaa 12y agoI've seen some AngularJS vs React benchmarks a while back. I believe it was http://jsperf.com/angular-vs-react/5 http://jsperf.com/angular-vs-react/5 I consistently got the result of Angular utterly and completely destroying React. Initially I blamed the virtual DOM approach, but after seeing other frameworks utilizing it and outperforming Angular by a huge margin, it seems to me that React is not written for performing well on small DOM documents. (There might be a turning point, considering how bloated Facebook pages it was designed for.)
- syntern 12y agoOur performance benchmarks suggest that application performance is most certainly better off with: (a) DOM reuse (b) calculating expensive things only once (c) reducing GC pressure == not discarding/recreating things (d) coordinating actions that may trigger reflow. It is independent of what framework you are using. My limited understanding of React is that it fails in (a), (b) and (c), and only limited measures can be applied to improve them. Re-creating the entire DOM on each update probably does not help. I have no information if (d) is possible with it. I am using Angular.dart for a while now, and it can be used to get all of them in an optimal way. Disclaimer: I'm working at Google.
- kaonashi 12y ago> Re-creating the entire DOM on each update probably does not help Perhaps you meant virtual DOM here? (in any case, the actual DOM is not recreated on every update)
- LukeHoersten 12y agoAnyone know of a Haskell or proper Haskell subset that can do something similar (hopefully batteries included)?
- takeoutweight 12y agoAbsolutely not "batteries included" but I've put some work into a React interface for Haste, which is a Haskell->JS compiler. https://github.com/takeoutweight/shade https://github.com/takeoutweight/shade
- LukeHoersten 12y agoAwesome. Thanks a lot.
- xkarga00 12y agoYou can run the tests by yourself here: http://evancz.github.io/todomvc-perf-comparison/ http://evancz.github.io/todomvc-perf-comparison/
- lightblade 12y agoI've been thinking why there's no virtual dom implementation other than react. Glad to see there's finally some out there.
- skybrian 12y agoIf you're using Dart, I have an experimental implementation: https://github.com/google/dart-tagtree https://github.com/google/dart-tagtree I'm sure others are experimenting as well, so we should see more implementations soon.
- baddox 12y agoMithril is a JS MVC that also has a virtual DOM implementation. http://lhorie.github.io/mithril/ http://lhorie.github.io/mithril/
- andrewljohnson 12y agoAll of the empty brackets to describe the virtual DOM looks bad to me. I'm curious if this is regarded as a language smell.
- wetmore 12y agoIt's easy to use partial application to get rid of that problem: the type of the function node is: node : String -> [Attribute] -> [CssProperty] -> [Html] -> Html We could define a convenient function div, for example, with div : [Attribute] - > [CssProperty] -> [Html] -> Html div = node "div" that would let us say "div [] [] [text "Hello world"]" instead of "node "div" [] [] [text "Hello world"]". Of course, this doesn't fix your problem with the empty brackets. This can be fixed with something like: bareDiv : [Html] -> Html bareDiv = div [] [] letting us do "bareDiv [text "Hello world"]"
- nickthemagicman 12y agoAnybody have any good reviews on elm?
- kasbah 12y agoIt is fun to play with and I managed to pick it up very quickly (after having already spent a significant amount of time learning Haskell). I am a bit concerned about the lack of typeclasses and what that could mean if I try and build something bigger using it. Maybe I could use Purescript and Elm together.
- judk 12y agoType classes are syntactic sugar for explicit dictionary (record) passing.
- danabramov 12y agoThere's another advantage to virtual DOM: you can hot-swap code while developing and have React run its diff algorithm without reloading the page. If your component has no (or little) side-effects, it means you get live reload as you edit for free. This is impossible with Backbone/jQuery soup of a view. See my proof of concept video: https://vimeo.com/100010922 https://vimeo.com/100010922 And actually runnable example that you can edit without refresh: https://github.com/gaearon/react-hot-loader https://github.com/gaearon/react-hot-loader I plan to write a blog post explaining how to integrate it into React project soon.
- dustingetz 12y agoYeah, the Om beginner tutorial demos this in lighttable with clojurescript, it's pretty epic. edit: https://github.com/swannodette/om/wiki/Basic-Tutorial https://github.com/swannodette/om/wiki/Basic-Tutorial
- danabramov 12y agoWhere can I take a look? In my case, this is pure JS, no Light Table or browser plugins needed. No messing with V8.
- swannodette 12y agoOm hot reload doesn't require Light Table or browser plugins, just eval support from your editor setup. There's no way to see this easily beyond going through the Om tutorial. But as you say this is just a benefit that more or less falls out of React if you're careful w/ state - Devcards is another ClojureScript example of the possibilities - http://rigsomelight.com/2014/06/03/devcards-taking-interactivity-to-the-next-level.html http://rigsomelight.com/2014/06/03/devcards-taking-interacti...
- lbotos 12y agoWhat editor are you using in that gif? Or is that just 10.10 that makes it look "cleaner"?
- glibgil 12y agoWhy so many strings and so few types, especially for somethings like Elm? The same in PureScript would be profile user = mkUI spec do div [ className "profile" ] [ img [ src user.picture ] , span [ text user.name ] ] See, types everywhere. https://github.com/purescript-contrib/purescript-react/blob/master/example/tutorial/tutorial.purs https://github.com/purescript-contrib/purescript-react/blob/...
- brandonbloom 12y agoBecause the underlying DOM is essentially untyped. This is a low-level adaptor library. One could easily build a more strictly typed wrapper on top.
- glibgil 12y agoLet me rephrase the question: why haven't they already?
- brandonbloom 12y agoWhy haven't you already? They're literally announcing the untyped base library layer and the post specifically calls out the desire to build higher level abstractions. Elm is moving incredibly fast, so your question is totally unreasonable.
- glibgil 12y agoI don't use Elm. I'm more interested in PureScript. But, the API looks silly for a Haskell like language. There is some positive feedback for whoever cares. Like, I wouldn't take that API out in public because everyone will think, "why is there string-based programming in Elm?"
- polskibus 12y agoI've never heard about mercury before! Great to see more virtual DOM development. I hope the new framework gets animation right, I'd love to see it as flexible as in D3, in my opinion this is something currently React currently lacks (the transitions are there but they are too simplistic to cover complex web app cases).
- chenglou 12y agoCare to try out https://github.com/chenglou/react-tween-state https://github.com/chenglou/react-tween-state? I've been experimenting with animation in React and would love to see the general paradigm behind this and implement it in React.
- loz220 12y agoHaving done some benchmarks with TodoMVC before, I knew something was off about these results. They play to the strengths of the virtual dom approach by manipulating the benchmark via dom instead of what ever interface was implemented within each TodoMVC implementation. So I forked the benchmark and changed both the Backbone and Mercury implementations to work through their respective apis. Here it is: https://github.com/smelnikov/todomvc-perf-comparison https://github.com/smelnikov/todomvc-perf-comparison as you can see the giant gap between Backbone and mercury is now gone while both tests perform the exact same tasks. (feel free to step through it in the debugger to see for yourself) Here's my commit log: https://github.com/smelnikov/todomvc-perf-comparison/commit/7e1a5f8f4150a6436b9eeba233102b64a2bd5a78 https://github.com/smelnikov/todomvc-perf-comparison/commit/... Note: I've added a new method to the Backbone implementation for toggling completed state as the old one was horribly in-efficient. This is not something inherit in Backbone but rather is specific to this TodoMVC implementation. See my comments in the commit log. Note 2: Exoskeleton, which is basically backbone without the jQuery dependency is roughly 2-3x faster than vanilla backbone, I'm going to predict that it will actually be significantly faster than mercury. Note 3: I think the virtual dom is great and seemingly has many benefits but I feel as though the speed benefit has been greatly exaggerated.
- vjeux 12y agoThe problem with those small benchmarks is that it's pretty easy to manually write the optimal sequence of DOM commands to get the best performance. But when you scale your front-end to millions of lines of codes with many full time engineers that may not know front-end very well, then it becomes extremely hard to do it properly. React originally was designed for developer efficiency and not performance. It is a port of XHP (in PHP) that we use at Facebook to build the entire front-end and we're really happy with. It turns out that the virtual dom and diff algorithms have good properties in term of performance at scale. If you have ideas in how we can communicate it better, please let me know :)
- Raynos 12y agoIn all javascript apps the part that is slow is the DOM, not the javascript interface. This benchmark was taken from the webkit source code then forked into http://vuejs.org/perf/ http://vuejs.org/perf/ then forked to include mercury then forked again to include elm. Neither elm nor mercury came up with this benchmark and just added themself to it. What this benchmarks shows is that async rendering is really fast. Mercury, vue & elm all use async rendering where DOM effects are batched and only applied once. A better, close to real user experience benchmark would be one using mousemove since that's an event that can happen multiple times per frame.
- batiste 12y agoElm seems Incredibly fast. By using requestAnimationFrame like described in the article I managed to bring my own library to satisfying performances https://github.com/evancz/todomvc-perf-comparison/pull/1 https://github.com/evancz/todomvc-perf-comparison/pull/1
- saurabhnanda 12y agoAs a startup who's built all of its UI on AngularJS, does introducing React/Om into the stack make sense? We have a B2B product where the users deal with a lot of CRUD forms and dashboards. React looks interesting, but only if it gives significant advantages (time-to-market, maintainability, etc) vis-a-vis AngularJS in managing a large code-base. Any first hand reviews?
- danabramov 12y agoWe used Angular at Stampsy and it was a pain to learn and debug. React is awesome because it encourages very modular components, has very small API surface (you can go far with knowing 5 API methods, compare this to Angular insanity) and great out-of-the-box performance (which is possible to boost 5x if you use performance hooks like `shouldComponentUpdate`). React gets you very close to browser limits in terms of perf, while staying very maintainable. Moreover, it doesn't impose any kind of structure on your projects, and you can begin using it one component at a time (even inside Angular). (I'm not affiliated, just a very happy user.)
- saurabhnanda 12y agoWhy do you say AngularJS was hard to debug? Also any insights around modularity - AngularJS directives vs ReactJS components? I hear you about the API surface. Currentlu AngularJS has too many weird/new concepts.
- danabramov 12y agoWhy I prefer React over Angular: 1. Two-way bindings complicate things because there is no single source of truth. (See http://vimeo.com/92687646 http://vimeo.com/92687646 at 30:00) 2. Template/directive separation is superficial, in fact these are single concern and should be together. 3. Separation between `props` and `state`, as well as documenting `props` via `propTypes` encourages very natural modularity.
- danabramov 12y agoWe used Angular at Stampsy and it was a pain to learn and debug. React is awesome because it encourages very modular components, has very small API surface (you can go far with knowing 5 API methods, compare this to Angular insanity) and great out-of-the-box performance (which is possible to boost 5x if you use performance hooks like `shouldComponentUpdate`). React gets you very close to browser limits in terms of perf, while staying very maintainable. Moreover, it doesn't impose any kind of structure on your projects, and you can begin using it one component at a time (even inside Angular). (I'm not affiliated, just a very happy user.)
- EvanYou 12y agoVirtual DOM is fast, but it's not the only way to provide free and fast DOM updates. The author removed the Vue.js implementation from the benchmark, which does not use Virtual DOM but is as fast or even faster than Mercury and Elm. Disclaimer: I'm the author of Vue.js. The benchmark is a fork of a fork of the Vue.js perf benchmark (http://vuejs.org/perf/ http://vuejs.org/perf/).
- girvo 12y agoAh! Well done on Vue. I'm finding it quite nice to play with outside work, currently we're using Mithril for our "small-non-angular" apps and components, but unfortunately while I adore it, a lot of the other devs Javascript isn't strong enough to deal with the flexibility Mithril gives you. Does Vue have the same issue? From what I've seen it sort of does, but with a bit more structure thus mitigating it a little. Thoughts?
- boubiyeah 12y agoWhat could possibly be done in the React.js version to make its performance closer to Mercury/Elm? I notice some 'shouldComponentUpdate' methods are already overwritten. Or is this the limit of an overly mutable language like js?
- deleted 12y ago[deleted]
- boubiyeah 12y agoAfter investigation, it turns out react has the potential to be faster than Om if it fixed its batched updates. Another huge performance issue is Function.prototype.bind which is called extensively. The Om example does some kind of Event delegation using channels which is much faster.