HVMN’s 90% Reduction in Server Response Time from React on Rails Pro

favoritesreact on railsSeptember 13, 2018Dotby Justin Gordon

The price we paid for the consultation + the React on Rails pro license has already been made back a couple of times from hosting fees alone. The entire process was super hands off, and our core team was able to focus on shipping new feature during that sprint.

HVMN Testimonial, Written by Paul Benigeri, October 12, 2018

HVMN.com
HVMN.com

Since HVMN installed React on Rails Pro, they’ve seen a roughly 90% improvement in server-response times. The gain came from a combination of intelligent caching along with a much more efficient Node React Server Rendering Engine.

Scout Graph: Deployment of React on Rails Pro React Fragment Caching
Scout Graph: Deployment of React on Rails Pro React Fragment Caching
Scout Graph: Deployment of React on Rails Pro Node React Server Rendering
Scout Graph: Deployment of React on Rails Pro Node React Server Rendering

“I looked at the Scout data on the performance changes after the deployments of both the fragment caching and the change from switching to a standalone Node React rendering engine, and I can confirm that the performance improvements were both significant beyond any doubt.” Derek Haynes, co-founder Scout.

Background

HVMN’s site is a Ruby on Rails app. The customer-facing side uses a single Rails view with a single React component. Routes are handled using react-router along with a Rails wildcard route. Because the site, like most e-commerce sites, depends heavily on SEO, the site server renders React on all pages. React on Rails handles integration of Rails with React. The Rails pages/index.html.hamlview contains one helper call to the React on Rails view helper react_component.

HVMN has been using React on Rails since late 2015. I got to know HVMN’s head of e-commerce, Paul Benigeri, after he got involved in the ShakaCode slack workspace and the React on Rails open source.

Paul reached out to me in late May 2018 to learn about how React on Rails Pro could improve the performance of HVMN’s e-commerce site, especially in regards to server rendering of React with Ruby on Rails.

3 Performance Enhancements

The addition of React on Rails Pro to the HVMN site resulted in reducing the server response times almost 90%. Scout reporting started with a median response time of around 1100 ms and dropped down to a median of about 120ms, an 89% improvement. New Relic showed a similar improvement of the average going from 953ms to 127ms, an 87% improvement.

React on Rails Pro offers 3 types of performance enhancements over the open source React on Rails. These performance enhancements were added sequentially to identify the impact of each.

1. Pre-Render Caching

This cache intercepts the server rendering request such that two requests with the same parameters will not result in JavaScript execution a second time. Of course, many factors come into play with the cache, including any changes in the JavaScript source files.

Pre-render caching provided a slight impact of from 2–5%, per New Relic and Scout data. However, the improvement was too small to be conclusive.

2. Fragment Caching of React Server Rendering

This type of caching is analogous to the Rails fragment cache view helper. The difference is that the React on Rails caching API is specific to rendering a react component. The programmer needs to consider cache keys in exactly the same manner as other fragment caches for Rails. However, in the case of React components, the cache key needs to be optimized based only on the props for rendering. The React on Rails Pro library handles all the other nuances of the cache key, including a determination if any serializers for the props have changed. The API is structured such that the calculation of props is placed in a block so that creating the props is not done if the cache key exists. the site Creating the props typically involves database queries and many string manipulations to convert the data into a JSON string.

Fragment Caching made the biggest difference in overall response times. Measuring the 3 days before and after fragment caching was added, Scout reported a 59% improvement in the median response time for the site’s main controller action (PagesController#index), from 943ms to 382ms. Similarly, New Relic reported the average execution time going from 953ms to 392ms, a 59% improvement.

3. Node React Server Rendering rather than Ruby Embedded JavaScript

I had suspected performance issues from using an embedded JavaScript VM inside of the Ruby VM. One thing that is for sure is that if there are any memory leaks in the JavaScript code from repeatedly running server rendering code. The React on Rails Pro Node Renderer utilizes a standalone Node server using a recent version of Node.js. A big advantage of standalone Node is that we can use proper Node tooling analyze performance and track down memory leaks.

React on Rails Pro Node React Server Rendering provided a healthy boost in performance. Measuring the 3 days before and after the rendering engine change, Scout reported a 69% drop in the median response time, going from 387ms to 120ms. New Relic reported a similar gain of 68% drop in the average response time.

Implementation

You might be wondering if it was difficult to achieve these gains. Installation of React on Rails Pro included installing the gem, turning on the pre-render cache and configuring the Node React Server Renderer. These steps required only configuration, rather than programming.

The enablement of React fragment caching required the same level of detail of any Rails fragment caching. The main steps were to identify efficient cache keys and to ensure that all props were fetched in the block passed to the React on Rails Pro view helper cached_react_component.

Contact Information

For additional details and confirmation of these results, feel free to email:

If you’re interested in trying out React on Rails Pro, please email Justin. You can find the documentation of React on Rails Pro here.

Comparing Scout vs. New Relic

The below screen grabs support the data above. I dug heavily into the available tools from New Relic and Scout. One thing I really liked about Scout was the ability to have a graph compare 2 periods. I show that in the graphs below. I couldn’t find any such feature from New Relic. One thing I did like about New Relic was that I could get data older than 30 days. Scout is currently limited to 30 days of historical data.

Scout Data

Scout profiling showing gains from React fragment caching
Scout profiling showing gains from React fragment caching
Scout profiling showing gains from the Node React Server Renderer
Scout profiling showing gains from the Node React Server Renderer

New Relic Data

New Relic showing the improvement of adding React on Rails Pro Node React Server Rendering
New Relic showing the improvement of adding React on Rails Pro Node React Server Rendering
New Relic showing before fragment caching, after fragment caching, and after adding the Node React Renderer.
New Relic showing before fragment caching, after fragment caching, and after adding the Node React Renderer.

Closing Remark

Could your team use some help with topics like this and others covered by ShakaCode's blog and open source? We specialize in optimizing Rails applications, especially those with advanced JavaScript frontends, like React. We can also help you optimize your CI processes with lower costs and faster, more reliable tests. Scraping web data and lowering infrastructure costs are two other areas of specialization. Feel free to reach out to ShakaCode's CEO, Justin Gordon, at [email protected] or schedule an appointment to discuss how ShakaCode can help your project!
Are you looking for a software development partner who can
develop modern, high-performance web apps and sites?
See what we've doneArrow right