We’ve often said, on this blog and elsewhere, that Ruby on Rails is the perfect framework for building MVPs quickly. This is still true. We’ve noticed, however, that once the user base starts to grow, the first issue to appear often has to do with performance. In this article, we’ll take a look at why this happens, and why it’s not RoR’s fault.
Reason 1: An approach focused only on the MVP
Products built quickly are not always built with the correct approach. MVP development is usually focused on delivering a base version of an app, one that could be used to start building a client base. MVPs perform operations set for them in the project requirements, but not much else. This means that performance can sometimes become less of a concern - and turn into a problem when the user base grows.
At iRonin, we avoid this problem by following the highest standards of software development from the start. We can improve app performance on many levels:
- database queries,
- response times,
- using external solutions to take over app responsibilities,
- codebase cleanup,
- software architecture.
Reason 2: Database queries
Inefficient database queries are a common bottleneck for Rails applications. When more and more users start to interact with an application, the product begins to performs slower. The first thing we want to do is check database queries, which are often written inefficiently. Usually, there are N+1 queries to fix, as well as overfetched data which is not used, and we need to preload necessary data.
Fixing queries will increase application performance immediately. Instead of sending multiple queries to the database to fetch data, we can do it using one simple query. Additionally, computing often occurs within the application. Moving calculations to the database is another way of increasing performance.
Reason 3: Response time
We can improve the response time of an application, which will increase the ratio of users who stay on web page. They may then convert to potential new clients or regular users of the application.
Many users are not patient. When a page continues loading for too long, the average user will quit and look for another solution. But we can decrease the response time of a web application by using caching. It will reduce response time on static pages and on pages which serve similar data or data that is refreshed rarely.
We like to use external services to cache application data, e.g. Redis. It’s the most popular service for this kind of operation. We also use caching for static pages so whenever a user enters this type of page, the application doesn’t process the whole request. It just serves the cached page.
Reason 4: Long lasting requests
Applications can have problems with long lasting requests. For example, user registration may require too much time. We can fix this problem by moving code related to some operations to external services to relieve application.
Often, actions within an app are bloated and all operations which should be done after a trigger event occurs (e.g. upon user creation), are done immediately and within same request. We can move these ‘after’ actions to an external service to be performed later on, or we can perform them asynchronously. For this, we like to use Sidekiq or Rake, allowing these tools to complete tasks which don’t affect the application or are not performed regularly.
A real life example
We once introduced the caching of API responses in an application. This reduced unneeded API requests. Whenever a user entered a product page, the product data was loaded, but when the product was visited a second time, the data was already stored in app, so the product was displayed instantly. Meanwhile, there was check in the background to make sure that the data had not been changed. From the user side, this solution feels very efficient, as the user does not need to wait to load up the products they’re browsing.
Reason 5: Too many items
Some application contains a lot of items. If so, filtering through them may take a lot of time. Basic searching tends to be done by simple SQL queries, which are perfect for a low amount of data. Even searching in large database might be done efficiently with SQL, but in most cases, when the data set is large, some new search options are required, adding complexity to the app.
We can solve this conundrum by improving SQL searching or moving the searching process to Elastic search, which is an external service dedicated for searching. It provides many solutions and plugins to control data and perform searching almost instantly. Whenever a search box is implemented in an application, the most popular way to list items is based on an entered phrase. Elastic search allows us to highlight the searched phrase in the list, for example, improving the experience. As it’s an external service, it also relieves the database from all this computing.
Reason 6: App architecture
If an app’s architecture which isn’t increasing performance sufficiently, we can reduce often reduce the number of allocated objects and reduce server memory usage. In extreme cases, this might even reduce the cost of hosting the application.
We like to use design patterns like SOLID, DRY, decorators, form objects, policies, etc. This allows us to have better control over application code and refactor bloated controllers or services which may affect performance. From the developer’s point of view, refactoring an application architecture increases readability. The whole code base becomes more clear, which makes it easier to implement new functionalities.
There are many solutions to app performance issues. Some of them are fairly simple and require gentle tweaks. Some are best implemented at the very start of development, and others require rewriting some code. If your business is suffering due to your app’s low performance, don’t panic. It’s almost certain that this problem can be fixed.
Are your users dissatisfied due to long loading times and slow calculations? We can help.
iRonin’s experts have commercial experience in upgrading existing apps to improve performance.
Senior Ruby on Rails Developer
Software developer mosty focused on backend. Like to experiment with frontend especially vue.js. In free time I watch all kinds of movies/series, play some video games and reading programming books.