Although the performance of an app in React depends on things like the browser running the code, the browser version, the device where our application is running, the latency of the network that the user has, etc. In this article, I want to share with you what we can do to improve performance from the React.js side.
First we must check our app for possible bottlenecks and errors, and in order to do so we can take advantage of some free tools that will help us greatly:
Sentry is presented as an "Error Tracking Software" and will allow your team to quickly find and fix bugs. If you want to learn more about Front-End Monitoring and how to get started with Sentry, please visit this link.
Profiler React dev tools:
As simple as installing the React Developer Tools extension in your browser of choice and inspecting an element on your page, to have the profiler and components option enabled and start measuring your application.
The profiler tab shows us how many times our page has been rendered under a certain action, how long it has taken, and why it has done so.
You are probably going to find a component that is not acting the way you were expecting but you can now make decisions on whether it is desirable to optimize the hierarchy of your components or if child components should render when their parent component does, and so on.
Let's say you have a search bar on your website that executes a function every time the user types in input, this function seeks to fetch data from an API call and displays the search results in real time.
Another example we see frequently on web pages is loading new items from a list of items on the screen. A third example would be if you have a listener to resize the screen, which calculates the dimensions.
If the user executes any of these actions several times, the function responsible for executing them will fire several times, and the performance of your website, or web application, will be affected.
Those are perfect examples to consider libraries like lodash and its debounce() method. A technique used to improve browser performance that allows a function to be executed only once, at the specified time-frequency since the last time the same function was called.
Memoise means to memorize a value to avoid processing it again, generally used to save you the cost of producing a value over and over again.
Now in react we have different ways to achieve the above, by means of the following techniques:
- React.memo(): is simply a higher order component (HOC) that wraps the component we want to store in memory. So if for example its parent component is rendered, react.Memo will validate if its properties have changed, and if not, it will not render it again.
This method should be used with great caution, as this comparison process can be more costly than rendering the component we are trying to avoid rendering.
Memo is ideal for components that:
suffers multiple renderings with the use of the application and generally receives the same props.
receives props that change infrequently or not at all.
very bulky components that have a very large impact on performance.
useMemo: This function is a React hook for memoising the value returned by a function. The useMemo function accepts two arguments and returns a value. The first argument is the function and the second, like useCallback, is a variable to watch, so a new value will not be generated until that variable changes.
useCallback: This hook allows us to memorize the function we pass it as an argument, always returning the same "instance" after rendering until one of the dependencies we specify changes.
When we talk about virtualizing a list or grid, we refer to rendering on screen only the elements that the user is currently viewing.
Virtualization in lists can be both horizontal and vertical (depending on the direction we indicate to the list) and for grids, the virtualization is both horizontal and vertical at the same time. To achieve virtualization, windowing techniques are used to calculate which elements should be displayed and which should not.
There are also several libraries that allow us to create virtualized lists but there are 2 that stand out from the rest: react-virtualized and react-window. Both libraries are from Brian Vaughn who is one of the developers of the React team.
Sometimes the final bundle of our application can have considerable weight and, in order to "see something" on the screen, users have to download all the information and this takes time.
This is where different code splitting techniques come to our aid.
As per MDN,
Code splitting is the splitting of code into various bundles or components which can then be loaded on demand or in parallel.
In this way, we ensure that when a page initially loads, a smaller bundle will be retrieved from the server. Using the dynamic import syntax, React.lazy, and Suspense, we can code split a React component.
There are also React code split libraries that can do this . Loadable-component are one of those.
If you are using some development dependencies in your application, it is important to check how much functionality you are using out of the large amount that is included by default.
This is where we can use tools like webpack bundle analyzer plugin that displays an interactive graph with the result of our bundle, what dependencies it contains and how much they weigh.
If after the analysis you find that you only used a small amount of css styles from the TailwindCSS framework, use tools like PurgeCss to help minimize the amount of css files in your final bundle.
Take a look at this list of tips on how to optimize your libraries with webpack.
If your backend is built on node.js and express you can use the compression middleware in the main file of your Node.js application. This will enable GZIP, which supports different compression schemes.
In addition to the default settings, you can customize your compression to suit your needs. There are several different properties you can use in the options object. For a complete list of properties, you can choose from, see the documentation here.
By applying certain techniques to a react application we can greatly improve performance. Many of these techniques or tips do not require sophisticated software but are free.
Although this was a small introduction to the world of web performance, don't hesitate to keep digging further into the subject and find more technical information on how to apply each of the techniques mentioned in this article.
Here I will leave you a list of interesting articles and if you want to contribute or help to improve this article feel free to leave a comment.
Profiler React dev tools: https://blog.openreplay.com/the-definitive-guide-to-profiling-react-applications
Code splitting: https://www.xenonstack.com/insights/code-splitting-in-react