How To Improve React JS Website Performance
Do you want to Improve React JS website performance? The best way to decide what performs better is to conduct experiments, compare them, and finally conclude.
Join the DZone community and get the full member experience.
Join For FreeAny company in the world needs to have an online presence to convey the value of its products or services. Websites, apps, and web apps are the mediums through which one can showcase their products in front of potential customers (collectively termed as front-end). Hence, a well-performing front end is the most important thing for modern businesses.
At Kommunicate, we use React JS with some plugins such as Webpack and Redux. A good and experienced NodeJS developer has a strong foundation of knowledge of various tools and libraries. Today, we will share the knowledge/experiments that we conducted to improve React JS website performance significantly.
Before diving deeper into it, let's make sure we are on the same page. First, we will discuss the basic data flow of how your front-end code gets served to users.
Whenever anyone opens up any website, the basic flow is:
- In the browser, the user enters the website’s URL and opens it.
- Browser interacts with the specified website’s server with some standard protocols.
- The server returns browser-understandable responses (In this case, it is all the code required to show web pages, i.e., HTML + CSS + JS files).
- The browser takes that response, processes it, and shows that in the dedicated window/tab.
The below diagram illustrates the same.
One must target multiple phases/levels individually to improve the website’s performance. In the above workflow, when the user navigates to the website, there are two phases:
- The browser gets the code from the server — code download time.
- The browser executes that code and generates UI elements — code execution time.
Improving phase 1 is easier than the 2nd one because it does not change with the programming language used for developing the front end.
In this blog, we will discuss phase 1, i.e., how to serve your code faster.
To make your code publicly accessible (or to deploy the code), there are multiple solutions:
- Use some cloud-hosted machine such as AWS EC2 or any other cloud service and deploy the code there.
- Create a Content Delivery Network (CDN) and host there (For example, Cloud front + AWS S3 )
- Use some service that handles all the human efforts of maintaining and scaling the system.
Let’s discuss these in detail.
Host the Code on Cloud
From the above image, you must have got some idea of how front-end code is served, right? If not, I’ll explain further.
This is more like an old-school concept and a pretty straightforward approach. All you need is a machine to build your project, run a server, and then host the build. Usually, no other complexities are involved in this. With this, you can get your front-end servers up and serve code in the form of UI to customers.
Broadly there are two ways to host the code on a cloud server.
Write Your Own Server Code
Write code to run the server and serve your build folder with it. In JavaScript, it might look something like this.
const express = require('express');
const path = require('path');
const app = express();
app.use(express.static(path.join(__dirname, 'build')));
app.get('/*', function(req, res) {
// index.html is entry point for most of the frameworks e.g. react, angular.
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
app.listen(3000, () => console.log("Example app listening on port 3000!"));
But it is not the only way. With the choice of programming languages, code might vary.
Use JavaScript Packages
There are many packages available to do so. One of the most popular ones in JS is Serve.
Pros and Cons of This Approach
Now let’s talk about the benefits and drawbacks of this approach.
Pros
- Easier to get things done.
- Not much effort is required.
- The cost of getting things up might be less.
- Every phase of serving the code to users is in your hand – all the small details are in your hands.
Cons
- Scaling is hard. The capacity of the serving code depends on how many machines you are using. Additionally, there will be a time when your server’s processing power will become a bottleneck, and requests will be processed slowly, i.e., the rate of incoming requests > completion rate. At this point, you’ll have two options to scale. Let’s see both:
- Vertical scaling — Increases the processing power of machines and adds more cores to the CPU. The bottleneck will still be there in the machine’s processing.
- Horizontal scaling — increase the number of machines involved. You might feel this approach is better, as you can always buy more machines as soon as you reach the bottleneck. But human work can become the bottleneck in this, as, at some point in time, you will be having 4-5 machines. And with each release, deploying code on those without affecting user experience will be tough.
- We all say that a machine is a cloud, but on the ground level, any cloud is just someone else’s PC ( at least for an IT professional). That is why that machine will have a geographic location. So, let’s say you have hosted your code on some AWS EC2 instances of the US region. Now the problem is no matter what your user’s location is (US, UK, IN, etc.), the code will be served from only one place. Since geographical distance will vary for each user, so do the time to download the code. The execution time of code is a different story.
To conclude, it is not a completely wrong approach; it is just a trade-off. As our CTO (Adarsh Kumar) says, everything is a trade-off. You have to choose among the available option with the best-fit approach. For example, for a startup with a shoestring budget, you might have to optimize the cost of resources, both humans and machines.
There is a high chance that you might not have a good DevOps team to handle all deployment processes. You might be able only to afford a single instance where you have to run your entire system (both backend and front end). In this case, it might be the best option, as there is not much headache as compared to other approaches. All you have to do is buy a cloud machine instance and a domain and run your code.
The Problem We Faced With This Approach
We were using a third-party module for hosting our React project. We were using this approach with code deployed on two Instances. After a while, the machine’s responses were coming slowly. For a temporary fix, we restarted the machine. Now, we had to find the root cause and fix it permanently.
After examining the system and logs and debugging it further, we knew there was some issue with File Descriptors. When a browser asks the server for some file (bundle code file), the server has to read the file from the machine’s local storage and return that data as a response to the request. Since we were using the third-party module, which internally handles all these things, we knew it was breaking due to a high load or lower package version.
We decided to move our front end to some other service where we don’t have to put more effort. The team can focus more on developing business logic rather than putting time into these overheads. Hence, we started exploring what other options are there and which one can suit us best.
Host on a Content Delivery Network (CDN)
This one is interesting, highly performant, and a little hard to get started with. With this approach, we will solve both the problems we faced in the first approach.
As mentioned on MDN, “A CDN (Content Delivery Network) is a group of servers spread out over many locations. These servers store duplicate copies of data to fulfill data requests based on which servers are closest to the respective end-users. CDNs make for fast service less affected by high traffic.”
So, the idea behind this approach is to use a set of machines over different geographic locations for hosting the same copies of your assets ( in our case, it is our front-end code). As your code is there on all major locations, download time for your website will be similar for all users depending upon their internet speeds.
But like any other approach, it also has some cons. Though there are many tutorials/blogs available, setting things up can be a little challenging. To find out more about how to set up this using Amazon CloudFront and S3, you can check amazon’s official documentation here.
Automate Maintaining and Scaling the System
Technically, this is the same as the previous approach. The only difference is that setup efforts are moved to some third-party services. There are many services available in the market you can try out any of them and see which one works better for you. So let’s talk about the experiment that we did at Kommunicate in the context of this approach.
At this point, we were sure about the things which we were looking for:
- CDN hosting.
- Better cache mechanism.
- Easy to automate and maintain with minimum human efforts.
The services in our mind were Netlify and Amplify. We decide to test both and compare the results of both. Here, I will show some stats on how well our production dashboard worked on Netlify and Amplify.
The best way to decide what performs better is to conduct experiments, gather facts, measure numbers, compare them, and finally conclude.
Hence, we hosted our codebase on both services with the same configuration and same build, note down the code download time for any five files, repeat this three times, prepare average states for each file, and then compare.
Comparison matrix of Amplify vs. Netlify serve time:
Note: We ran this experiment in April 2020. After that, there were many improvements made by Amplify, Netlify, and Kommunicate team itself. So, the present results might be different than the above-shown data.
Published at DZone with permission of Devashish Mamgain. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments