At any given time in the history of software development, there has always been a tension: more abstraction or less abstraction?
Like many things in life, there is a pendulum that tends to swing back and forth. It’s hard for the human brain to reason about exponential improvement, so even though people understand Moore’s Law, their thinking still tends to revert to linear improvement when making projections.
So if you go back to technical books from the 70s, they tend to make statements like, “It seems unlikely that interpreted languages will ever be able to do anything serious.” And yet here we are, powering billions of dollars of business on top of interpreted languages.
Eventually people realize that the higher abstractions allow them to be more productive, and that the performance trade-offs tend to be minimized over time. This is why, in my opinion, Ruby on Rails won: it front-loaded better abstractions and took the performance hit, knowing that eventually, it wouldn’t really matter. And developers were much more productive than when they had to wrestle the ceremony of Java, for example.
But it is easy to see temporary performance gains when you strip away abstraction, and then decree that you have eliminated bloat and waste and inefficiency. Sure, but you’ve also given up lots of productivity. Over time, the abstraction becomes cheaper for free, but your productivity doesn’t get better for free.
To me, people advocating Node as a replacement for Rails are like the HR manager that looks at the budget and realizes how much money is being spent on IT, so she lays them all off and outsources the job. At first, everyone is happy, because, wow! look at how much we’re saving! But a few years down the line, everything has gone to shit and users have to do more and more for themselves.
Java developers laughed at Rails as a slow toy. Node proponents are warning Rails developers, now, that they are making the same mistake. But I don’t think the scenarios are analogous. Rails' value proposition was: “We’ll offer you better abstractions, and we think they’ll get faster over time.” Node’s value proposition is: “We’ll offer you low-level abstractions, and they’ll be faster. You’ll just have to do more work yourself.”
Computers and frameworks get faster over time without any effort on my part. Code I’m responsible for, though, just sits there unless I do something to it.
In the end, I always bet on higher abstractions.
Another thing to note is that, based on my observation, most people have very little idea on how to measure what really matters when they discuss things like speed. Essentially, the only way to reasonably argue that Node is faster than Ruby/Rails is actually if you build the same exact thing using different architectures. While I do see the catch-22 here and I do realize that there things that you can isolate and test with both Node and Rails, most of the benchmarks that I have seen so artificial that they are barely useful.
In any reasonably big web application, things that tend to matter in terms of speed rarely happen to be what language you use on the front-end level (where I am using front-end to mean language used to serve content, not client-side JS). At the end of the day, you’ll have to take anything that takes more than a couple tens of miliseconds (or maybe hundreds) offline anyway. And it turns out all PHP (what we used at Yahoo), Python (what we used at Digg and what we use at Snapguide) seem to be fast enough to consume any queues. In case you need something way, way faster than those, which is very rarely the case, sure, go ahead and use whatever language you fancy.
My point is, sure Node is definitely faster in some aspects but I’ve yet to see be faster enough to matter, especially for the kinds of apps that most people seem to be using them for. At the end of the day, it really boils down to personal preference informed by how fun it is to develop, how easy to find help, how good are libraries that do stuff that you’d not want to do, or as you said productivity boost. In my experience, Rails hits that sweet spot better with web development while Python is somewhat nicer at times to whip out random stuff. But, to each his own.
One thing that has always frustrated me about these kinds of benchmarks is that “hello world” for a web framework can mean wildly different things.
For example, a “hello world” response in Rails will:
In short, comparing how fast Node can put a String onto a socket with how fast Rails can render a response is an apples-and-oranges comparison. And because we’re usually measuring responses on the order of a few milliseconds (2,000 requests per second is a 0.5ms response, while 500 requests per second is a 2ms response), it’s easy to get caught up in seemingly large numerical differences that really reflect a millisecond or two of overhead.