Visitors, Developers, or Machines

I keep my feet squarely planted in two worlds when it comes to development. One of those is all things front-end, and the other is Ruby (and Rails).

With Ruby/Rails, they’re frequently maligned as a not-serious programming language/framework pair because they focus on developer happiness more than pure performance. They follow a philosophy that the productivity gains from a happy developer far outweigh any performance losses from being less performant. That’s not to say that they outright ignore performance, but it isn’t the only or even primary goal. Nor should it be.

So Ruby gets a bad reputation for not putting performance above all other things. On the other hand, despite a deeper understanding and increased attention to performance in front-end development, the most popular front-end frameworks are going in an entirely different direction. These heavy JavaScript frameworks give some benefit to perceived performance once the JavaScript is loaded and cached, but oftentimes, pages that could be trivially lightweight and work fine end up including significant overhead in the form of frameworks.

I’ve been trying to understand the appeal of these frameworks by giving them an objective chance. I’ve expanded my knowledge of JavaScript and tried to give them the benefit of the doubt. They do have their places, but the only explanation I can come up with is that developers are taking a similar approach as Ruby and focusing on developer convenience and productivity. Only, instead of Ruby’s performance being tied to the CPU level, JavaScript frameworks push the performance burden to the client.

In both cases, the tradeoff happens in the name of developer happiness and productivity, but the strategies have entirely different consequences. With Ruby, the CPU is still (mostly) the responsibility of the development team, and it can be upgraded. With JavaScript, the page weight becomes an externality pushed onto visitors.

Increased bandwidth costs may be somewhat of a concern to the developer, but with the exception of the savviest organizations, I’m not aware of front-end developers giving significant consideration to bandwidth bills. Bandwidth costs might receive lip service, but given that the average page weight has gone from about 500Kb in 2010 to almost 2,000Kb in 2020, the evidence shows it’s not a significant consideration.

The unfortunate reality with pushing the performance burden to the front-end is the lack of reliable connections, and those aren’t just about being hard-wired to fiber or on mobile. Everyone at some point has a less-than-stellar connection even if only from concrete or metal walls and roofs, and it becomes crystal clear when a site works well on a thin connection. Disasters are a great example of this. Connectivity can be incredibly limited when disasters affect infrastructure.

The performance tradeoff isn’t about where the bottleneck is. It’s about who has to carry the burden. It’s one thing for a developer to push the burden onto a server they control. It’s another thing entirely to expect visitors to carry that load when connectivity and device performance isn’t a constant.

Developer productivity is a great metric, but it can’t be isolated from the larger ecosystem. With Ruby, the tradeoff works because nothing is externalized, and it’s barely even a tradeoff these days. But with large front-end JavaScript frameworks, things aren’t just slow. If that JavaScript isn’t able to be loaded for a variety of reasons, sites don’t just become a little slower. They break entirely.

JavaScript isn’t inherently problematic. Using JavaScript in a way that leads to complete failure is the problem. Layering in something like Turbolinks provides the performance benefits of the larger JavaScript frameworks, but the difference is that Turbolinks is smaller, and, even if it doesn’t load, the site can still work.

There’s promise in the front-end frameworks. They’re not entirely bad or wrong, but the gains in developer productivity shouldn’t come at the expense of the visitor. It may not be fashionable, but rendering usable HTML on the server and then sprinkling in progressive enhancement via CSS and JavaScript is still the best all around experience for the people visiting the site. That’s the direction these frameworks should be heading.