Before we kick off with this article, I want to offer up a quick disclaimer: I don’t hate Rails as a framework. In fact, I consider myself a fanboy of Rails. The framework itself is SO beginner friendly, and I love the fact that it is easily maintanable (for small projects) and tends to open itself up for collaboration.
Below are the few wonderful things about Rails:
- The community is strong
- It’s a beginner friendly framework
- It has support for pragmatism
- It’s got the best standards and practices
- It enables fast development
- It’s very easy to migrate and modify
Ruby on Rails, which is an open source web application framework for the server-side, operates on Don’t Repeat Yourself(DRY), which provides a standard setup convention.
It is still MVC (Model-View-Controller) architecture based. Again, one good thing about Ruby on Rails to me is its fast development. That got me —it’s really perfect if you are under the pressure of a short deadline or a low budget.
That being said — Rails is annoying! And I will be giving a few notes on where things went wrong in Rails from my perspective as a developer.
Yeah — those are just tweets. But let’s get down to serious business.
Speed and performance
Huge projects with large-scale traffic tend to have slower speed and performance compared to other frameworks like Django, Go, or Node.js. While this can be blamed on the developer rather than Rails, it isn’t always obvious that the developer is the problem.
Rails is a powerful and nice tool, but when misused by inexperienced developers, performance can take a very bad hit. Having a bad architecture drops the performance. Also, too much memory is consumed. As a result, garbage collectors take a while to perform.
So, issues regarding performance still boils down to server or database architecture, rather than Rails itself.
Unlike languages like Go and C++, which are compiled, Ruby and Rails require more time to execute code.
One good side is that you can make your application faster with code optimization, caching, and scaling. To achieve the same performance with Rails as you do with other frameworks like Django, you might need to spend more money and time on a better server infrastructure. Obviously, that can be a pain.
Optimization is an oft-forgotten aspect of Rails development with the lucidity of quickly throwing in some gems, queries, Active Records, and deploying your project. You’ll most likely find your article struggling in the performance area. Although this article isn’t a ‘How to optimize your Rails project’ , articles from Cheyne Wallace give a guide on this.
Rails has been the choice framework when it comes to fast development or low budget projects, but that has been a bottleneck for some developers.
Most of its dependencies and modules — if not all — come out of the box and disregard customization. Developers tend to configure modules, most especially database migrations and routing, which can be pretty daunting when you have a project in mind that might need a different or unique setup.
Is this really frustrating for all developers? I wouldn’t say all, but I can pretty confidently say that a fair amount of developers have some complaints about this.
The point is, Rails has it all! Rails is crazy about gems(a library used in your application). While this is good for developers that just want to jump into a project and get things done quickly, it is annoying for some when you have to use things that don’t feel right for your project. Additionally, it can be annoying if you want to build something extended or unconventional.
Too much magic
A lot of magic happens in Rails, meaning that things happen behind the scenes and you often don’t know how or why. I believe this gives every developer freedom, but can also make them prone to unnecessary mistakes. More specifically, the Ruby on Rails code looks simple. On the contrary, it’s actually very complex at the same time. A single line of code could take or perform a lot of actions and connect to gems (libraries).
I kind of feel like Rails loads too many things at the very beginning of development. Moreover, most of these things do not actually get used by the developer. Ultimately, this causes high CPU usage and slows things down.
The complex capabilities of Rails may seem awesome, but a lot of what happens in a line of code might be unknown. Naturally, every developer has their own opinions about this. For a lot of developers, this opinion is not favorable. In addition to unnecessarily slowing things down, the amount of actions performed in a single line of code in Rails makes it hard to maintain.
Less web hosts
Ruby on Rails is more resource-demanding than some other popular frameworks. It requires more CPU usage, which some web hosts might not give. Hosts that are Virtual Private Servers are much more convenient, because they do not support the physical server in the sense that resources like RAM and CPU are not a consideration.
The point is that not all web hosts can keep up with most Rails projects.
Dealing with the frustration (performance)
Those are my biggest frustrations with Rails as a framework. However, it’s quite obvious that performance and speed degradation are not based on Ruby and Rails alone. That’s good, because it means there are solutions.
One solution to the performance problem is caching. The few pages that are most likely to be opened by the user should be cached. This alone improves your performance. The issue of rending these pages, which may contain content blocks, reduces performance, so it is best that you cache them.
Second, you can make your assets external. Assets like that of the important resources (including images, fonts, etc.) for your pages can be big, small, or heavy. Whatever the size, you just have to host them. This offloading away from your server really increases the performance.
Another way you can improve your performance is by using Unicorn for Heroku. Unicorn is a multi-threaded server (or web worker) for Rails in particular. This handles connections by doubling and tripling its amount. A web worker handles one connection, 5 workers handle 5 concurrent connections, and so on.
You can also use eager loading to boost query performance, and utilize indexing to boost database performance.
Finally, remember: Don’t repeat yourself (DRY). This is really common advice, but a lot of developers neglect to follow it.
These are the most common solutions most developers tend to use when using Ruby, and they can make a real difference when it comes to your performance and make your experience with the framework a lot better.
Overall, I like the fact that Rails supports the idea of convention over configuration. It’s time-saving, and enables you to write more business logic code and lay less groundwork that has no connection to the business code.
While it has its advantages, Rails is wrong on a few things. Rails is definitely not flexible — in fact, it is bottled into a one-way mechanism. Rails also doesn’t seem easy to scale up for large projects.
In my opinion, the creators of Rails take convention over configuration a little too far. As a result, they reduce the flexibility of users’ pattern in favor of patterns in-built in the framework. This has made trending concepts complicated to implement without sacrificing on other choices.
Upcoming releases seem pretty promising. Most of the downsides are being fixed, and more features are being added. Rails should be on track to improve in the future.
Rails is the ideal choice if you have deadlines and budget requirements that require fast development. But a more flexible framework like Django is probably a better option otherwise because it allows you full control. Heavy real-time applications, which always require faster performance and scalability, will require consideration if you’re planning to use Rails.
LogRocket: Full visibility into your web apps
LogRocket is a frontend application monitoring solution that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.