This post is "benchmarketing". The post says: "Here we add a key to each entry and define shouldComponentUpdate for the Todo component. Essentially the same as what we did in Elm, but we have to write some logic to figure out if a Todo changed. This opens us up to some extremely tricky bugs." The author should instead be using immutable.js, so that checking for changes is object identity checking; it's much faster that way and avoids "extremely tricky bugs".
Honestly benchmarks are useless. I'm sure Elm is "faster" and what not... but does it really matter? React is fast enough for a ton of businesses and people. So is Ember.
Sure, performance is good, but I think mostly bottlenecks are user code and the way the JS/CSS bundle is loaded and delivered. If there's a major performance issue in the framework, just submit a bug report. It'll be fixed.
I'm more interested in how productive I can be and how much fun I can have coding with said framework or language—something both Elm and React do well.
React has never been about speed (if you look at the official dev posts, speed is never listed as a top priority) but rather about not being slow (sCU check and whatnot). It's the slowest vdom implementation I know of, but it's fast enough and the network effects from being the biggest make it good enough. If you're interested in faster vdoms then check out inferno (fast), snabbdom (simple), mithril (compact), or domvm (flexible).
Speed is one thing, but the fact that you must replicate your business model client AND server-side with Elm is a huge minus. I would take ScalaJS over any 4 of those frameworks any day.
You've got datomic on the server and datascript on the client, transit on the wire, reader conditionals to share code and much more. Plus everything can be modified as its running.
When it comes to web frameworks I don't really care about performance as much as I care about managing complexity. Which is why I'm looking at om.next over all the other frameworks.
And managing complexity is not something you can benchmark in toy projects - every single framework is virtually the same at such a small scale.
I guess as a professional Python developer, it would take some time to get used to all the parentheses. I've used Emacs for 20+ years, but outside of elisp I've never been comfortable with s-exprs.
I think the languages aren't really comparable from a maturity and support pov. Clojure is mainly done by hobbyists and enthusiasts. There is a large gap in terms of tooling that can't be closed in a few years.
I have a hobby project that uses Elm on the front end with Elixir and Phoenix on the back end, and that has been working really well. Elm's event machine like architecture goes well with Phoenix's native support for channels, although the elm library for Phoenix Channels is definitely not production ready.
It has been a very bizarre experience having dynamic typing on the back end and static on the front end, though. Everything feels slightly topsy turvy.
Whats the difference between a few seconds of loading time for a site that only needs to load its bundle once? Sure its nice for it be faster but the main benefit I thought is you don't need to reload pages as you navigate.
Possibly misunderstood the article, but it seems they are comparing performance once the bundle is already loaded. That said, as someone who personally prefers using browser over apps ( at least for content consumption, rather than something like a password manager) it is nice to have things boot up quickly.
"Speed in Milliseconds" should be changed to "Time in Milliseconds". More speed is a good thing, but more time is not. Using "speed" instead of "time" in the chart title makes it sound like bigger bars are better, but that's just the opposite. Plus, speed isn't even a measure of time (like milliseconds); it's a unit of distance (or some equivalent) divided by time.
Those benchmarks should be done by someone independent from one of the tested frameworks though. Hard to trust the methodology, especially with Elm emerging as the "winner".
1. That benchmark is rather outdated - React 0.10, Angular 1.2.14 ...
2. Article seems to compare most popular frameworks, so no surprise Mithril didn't make it since more popular frameworks like Vue are also not on the list
The documentation for Effect Managers is basically "If you don't already know how to make one, you shouldn't be making one." I get that it's an "expert feature", but I want to learn and try anyways! I've been learning the basics by looking at the WebSocket library, and reading the compiler errors when I broke it in different ways. The compilers errors were surprisingly helpful, but some documentation would be nice.
The core language docs are ok. --> If you know Haskell!
The architecture docs are ok. --> If you already understand the concept and are willing to read some other tutorials.
The effects docs are... no comment.
Compare the guide to others like from Rust.
A lot of people I've pointed to Elm gave up quickly because there s no good introduction guide.
It's not even properly linked as a first, visible entry in on the docs page.
Honestly, your decision to use any of the frameworks in the article should not be based on a benchmark. The frameworks here differ so much in how they work, the mental thought process you use in them, etc.
What is the technical debt of Elm? Training for developers to learn something other than JS, etc. This is a much bigger factor in a framework decision than a benchmark. Especially when all of them are fast and only a few cases would you even notice a difference between them.
Please, don't use this to decide which front-end framework to use. Nor switch from one you are using, "just because it's faster!". Save yourself and your co-workers the headache.
I very rarely see technology choice decisions based on performance. It probably should happen more often then it does. If anything most choices are based on popularity.
Benchmarks are not the best way to advertise languages but regardless Elm has do well on so many fronts to make it competitive otherwise it will die to the popular frameworks/languages (usually the lowest common denominator).
> Please, don't use this to decide which front-end framework to use. Nor switch from one you are using, "just because it's faster!". Save yourself and your co-workers the headache.
I would hope and fairly optimistic that people make decisions on a variety of compelling reasons (particularly tech people). Some of those reasons often can be performance. What you mean is don't make this the sole reason and even this "tip" isn't really helpful advice.
There is one benefit of choosing based on popularity - it becomes easier to hire for, and more likely to find engineers enthusiastic about the work. In addition, it increases the number of eyes on it, which can surface difficult bugs/edge cases to get addressed.
> There is one benefit of choosing based on popularity - it becomes easier to hire for, and more likely to find engineers enthusiastic about the work. In addition, it increases the number of eyes on it, which can surface difficult bugs/edge cases to get addressed.
I didn't mean to sound like it isn't a good idea to have a good portion of your reasoning based on popularity. I have done it myself :) . But if your trying to make your framework popular you have to do some advertising (hopefully somewhat honest). I don't blame the Elm devs for publishing some benchmarks particularly when it is some impressive work they have done.
I believe the saying is "Lies, damn lies and benchmarks".
That said, he does make a case that elm is competitive with other frameworks, which is all anyone should take from a language benchmark, in my opinion.
None of them is known to be really fast and the benchmark tells, they all range in the same order of magnitude. So why not include Inferno, Mithril or Preact? Only a few of them are mainstream, so why mess with stuff that is neither popular nor known to be fast.
For the love of * (pick your preferred deity, I'm going with Flying Spaghetti Monster), stop benchmarking on ridiculously simple TodoMVC apps.
They are not at all representative of the complexity costs that emerge from real apps, which often mitigate differences between frameworks considerably.
(Apart from the fact that creators benchmarking their own framework know how to optimize it best).
I'd rather see articles about how to manage complexity at scale rather than about performance in apps so simple you'd be better off in raw javascript anyways.
Show me a framework which handles optimistic updates, knows how to query multiple data sources and merge their values, doesn't make it harder to reason about as I add more components and then I'll be very interested.
These are only a few of the hard problems to solve when building an app and I feel most frameworks completely ignore them and instead take the easy route of how quickly can I write yet another TodoMVC.
Productivity at the beginning of a project doesn't matter nearly as much as productivity at the end of a project.
react fanboys are gonna be a little upset that you showed that angular is faster in your benchmarks. They spent months flooding internet saying react was faster and you're contradicting that.
Please elucidate? Angular 1.5 has one-way binding, lifecycle hooks, component tree architectures. UI-router is well on the way to become framework agnostic. Redux or redux-style state management is possible with ng1.5, and a pleasure with ng2.
On top of all of that, you get the benefit of using a framework instead of patched together libraries. Basic tools like intercepting all http traffic at the request/response level is incredibly helpful with larger apps.
The only differentiating factor really left is JSX, and while that may be a personal preference, angular style templating is a lot more comfortable for developers used to server-side templating (JSP, Razor, et al)
Likewise, beside custom "directives" (tag libraries) being a bit complex at first. Otherwise, you just start with a page mockup, then progressively refine it by loading some scripting and view models for the data entry or variable substitution.
Angular 2 on the other hand. One of my coworkers (to paraphrase) felt like it was GWT all over again (and I agree).
As someone who has started to explore (and enjoy) elm, I have to say that speed is not one of the major selling points for me. Rather, seeing that it has at least competitive speed is just dodging a potential deal breaker. It could smother me in kittens and do my taxes, but if a framework only renders three frames per second, I definitely won't use it. Elm being in the same ballpark (slightly better? slightly worse? doesn't matter) means that I can see if the other features of the language entice me to try it out. They did, I did, and I really like it (even though apps that use random a lot end up being structured in a way that is strange to my brain).
I recently heard Evan give an overview of the language and everyone in the room came away excited.
The speed is really just a bonus, as the real things to be excited about are the features you get from a typed functional language (HM type inference, union types, auto currying, etc.) that compiles to efficient JS with a focus on web development.
As a React user, I'd be really curious to see what these benchmarks look like when you're dealing with larger, more complex projects. I was under the impression that React scales well when dealing with lots of nested components and diffing the updates for each.
It "scales well" because of shouldComponentUpdate. That lets you avoid building huge chunks of virtual DOM as your app becomes very large.
The trick is that the same exact optimization is available in Elm and Angular 2 (with different names) so the same argument applies there as well.
The "Do these results generalize?" section makes an argument as to why the numbers you see on a simple TodoMVC app should generalize to apps of any size. When everyone has the equivalent of shouldComponentUpdate, the question becomes: when you finally DO need an update, how fast is it? That can be measured in small apps.
Every single comment here is focused on just one aspect of this article: speed. Far more interesting points the article covers are around _how_ Elm optimizes and _how_ developers optimize Elm code. From the conclusion:
- Optimizing Elm only touches view code, unlike everyone else.
- Optimizing Elm cannot introduce sneaky bugs, unlike everyone else.
- These results should generalize to apps of any size.
Also interesting is how Elm's immutability allows it to use requestAnimationFrame by default, which plain vanilla JS libs can't use by default.
A related anecdote: One of the major reasons I decided to give elm a try was when Richard Feldman was giving a talk about writing Dream Writer in elm, and he got to a point where the performance was noticeably slowing down. He started trying to make it better by 'sprinkling a few `lazy`s through the view code', and then stopped because that had magically made everything super fast again.
54 comments
[ 2.8 ms ] story [ 106 ms ] threadSure, performance is good, but I think mostly bottlenecks are user code and the way the JS/CSS bundle is loaded and delivered. If there's a major performance issue in the framework, just submit a bug report. It'll be fixed.
I'm more interested in how productive I can be and how much fun I can have coding with said framework or language—something both Elm and React do well.
You've got datomic on the server and datascript on the client, transit on the wire, reader conditionals to share code and much more. Plus everything can be modified as its running.
When it comes to web frameworks I don't really care about performance as much as I care about managing complexity. Which is why I'm looking at om.next over all the other frameworks.
And managing complexity is not something you can benchmark in toy projects - every single framework is virtually the same at such a small scale.
But I actually like Javascript.
I guess as a professional Python developer, it would take some time to get used to all the parentheses. I've used Emacs for 20+ years, but outside of elisp I've never been comfortable with s-exprs.
I had never heard of om.next. I think this is what you mean: https://github.com/omcljs/om ?? correct?
> And managing complexity is not something you can benchmark in toy projects - every single framework is virtually the same at such a small scale.
Well, looking at how much garbage was needed to implement todomvc in Backbone kept me from considering it any further :)
And in this you were wise! Or at the very least fortunate.
I think the languages aren't really comparable from a maturity and support pov. Clojure is mainly done by hobbyists and enthusiasts. There is a large gap in terms of tooling that can't be closed in a few years.
It has been a very bizarre experience having dynamic typing on the back end and static on the front end, though. Everything feels slightly topsy turvy.
It's about rendering time, when everything is already loaded.
http://lhorie.github.io/todomvc-perf-comparison/todomvc-benc...
2. Article seems to compare most popular frameworks, so no surprise Mithril didn't make it since more popular frameworks like Vue are also not on the list
(Coming from someone who appreciates Elm)
The architecture docs are ok. --> If you already understand the concept and are willing to read some other tutorials.
The effects docs are... no comment.
Compare the guide to others like from Rust.
A lot of people I've pointed to Elm gave up quickly because there s no good introduction guide. It's not even properly linked as a first, visible entry in on the docs page.
Honestly, your decision to use any of the frameworks in the article should not be based on a benchmark. The frameworks here differ so much in how they work, the mental thought process you use in them, etc.
What is the technical debt of Elm? Training for developers to learn something other than JS, etc. This is a much bigger factor in a framework decision than a benchmark. Especially when all of them are fast and only a few cases would you even notice a difference between them.
Please, don't use this to decide which front-end framework to use. Nor switch from one you are using, "just because it's faster!". Save yourself and your co-workers the headache.
Here is more info about one company's experience with Elm when it comes to technical debt, training developers to learn something other than JS, etc:
https://www.youtube.com/watch?v=R2FtMbb-nLs
Benchmarks are not the best way to advertise languages but regardless Elm has do well on so many fronts to make it competitive otherwise it will die to the popular frameworks/languages (usually the lowest common denominator).
> Please, don't use this to decide which front-end framework to use. Nor switch from one you are using, "just because it's faster!". Save yourself and your co-workers the headache.
I would hope and fairly optimistic that people make decisions on a variety of compelling reasons (particularly tech people). Some of those reasons often can be performance. What you mean is don't make this the sole reason and even this "tip" isn't really helpful advice.
I didn't mean to sound like it isn't a good idea to have a good portion of your reasoning based on popularity. I have done it myself :) . But if your trying to make your framework popular you have to do some advertising (hopefully somewhat honest). I don't blame the Elm devs for publishing some benchmarks particularly when it is some impressive work they have done.
That said, he does make a case that elm is competitive with other frameworks, which is all anyone should take from a language benchmark, in my opinion.
None of them is known to be really fast and the benchmark tells, they all range in the same order of magnitude. So why not include Inferno, Mithril or Preact? Only a few of them are mainstream, so why mess with stuff that is neither popular nor known to be fast.
They are not at all representative of the complexity costs that emerge from real apps, which often mitigate differences between frameworks considerably.
(Apart from the fact that creators benchmarking their own framework know how to optimize it best).
Show me a framework which handles optimistic updates, knows how to query multiple data sources and merge their values, doesn't make it harder to reason about as I add more components and then I'll be very interested.
These are only a few of the hard problems to solve when building an app and I feel most frameworks completely ignore them and instead take the easy route of how quickly can I write yet another TodoMVC.
Productivity at the beginning of a project doesn't matter nearly as much as productivity at the end of a project.
On top of all of that, you get the benefit of using a framework instead of patched together libraries. Basic tools like intercepting all http traffic at the request/response level is incredibly helpful with larger apps.
The only differentiating factor really left is JSX, and while that may be a personal preference, angular style templating is a lot more comfortable for developers used to server-side templating (JSP, Razor, et al)
Unfortunately, that's an expensive test.
Angular 2 on the other hand. One of my coworkers (to paraphrase) felt like it was GWT all over again (and I agree).
The speed is really just a bonus, as the real things to be excited about are the features you get from a typed functional language (HM type inference, union types, auto currying, etc.) that compiles to efficient JS with a focus on web development.
<1500 lines of straightforward JS makes it all possible. It is indeed very similar to Matt Esch's original [1]. The Elm port reads nicely in one file.
[1] https://github.com/Matt-Esch/virtual-dom
The trick is that the same exact optimization is available in Elm and Angular 2 (with different names) so the same argument applies there as well.
The "Do these results generalize?" section makes an argument as to why the numbers you see on a simple TodoMVC app should generalize to apps of any size. When everyone has the equivalent of shouldComponentUpdate, the question becomes: when you finally DO need an update, how fast is it? That can be measured in small apps.
- Optimizing Elm only touches view code, unlike everyone else.
- Optimizing Elm cannot introduce sneaky bugs, unlike everyone else.
- These results should generalize to apps of any size.
Also interesting is how Elm's immutability allows it to use requestAnimationFrame by default, which plain vanilla JS libs can't use by default.