Improve Performance of Web Application — React JS

Sourabh Sinha
Jun 20 · 4 min read

Performance related problems in web application is not new. Developers have been encountering these issues in almost every project they work on. React is one among such languages which is considered to be best in terms of delivering performance. Since the virtual DOM of react is popular for rendering components effectively, it becomes more important to focus on performance.

Here are few tips which helped me to improve the performance of my application while working on improving the lighthouse score.

Remove all inline functions

Function that is defined and passed down inside the render method of a React component is called an inline function.

Let’s try to understand this with a simple example of how an inline function may look like in a React application.

import { useState } from "react";export default function App() {
const [count, setCount] = useState(0);
return (
<div>
<h1>Hello CodeSandbox</h1>
<h1>{count}</h1>
<button onClick={() => setCount(count + 1)}>
Increment
</button>
<button onClick={() => setCount(count -1)}>
Decrement
</button>
</div>
);
}

In the above example, the onClick prop is being passed as an inline function that calls setCount. The function is defined within the render method, often inline with JSX.

In the context of React applications we often see such coding pattern. This increases the memory footprint of the app and will always trigger the re-render even when the props don’t get changed.

This is mainly because method passing is always pass by reference, thus it will create a new function and change its reference for every render cycle.

Solution:

The simplest way is to move all inline functions outside the render method such that it does not get redefined on every render cycle. This will reduce the memory footprint.

import { useState } from "react";export default function App() {
const [count, setCount] = useState(0);
const increment = () => {
setCount(count + 1);
}
const decrement = () => {
setCount(count -1);
}
return (
<div>
<h1>Hello CodeSandbox</h1>
<h1>{count}</h1>
<button onClick={increment}>Increment</button>
<button onClick={decrement}>Decrement</button>
</div>
);
}

Use Eslint-plugin-react

It is recommended to use ESLint plugin for almost any JavaScript project and React is no different.

With eslint-plugin-react, we will be forcing ourselves to adapt to a lot of rules in React programming that can benefit our code on the long run and avoid many common problems and issues that occur due to poorly written code.

Dependency optimization

It is worth checking how much code we are actually utilizing from dependencies while considering optimizing the application bundle size.

Let’s take an example of lodash which is widely used by the developers. It is a JavaScript library that helps programmers write more concise and maintainable JavaScript. Say we are using just 20 out of the 100+ methods available in it, then having all the extra methods in our final bundle is not optimal.

So for this, one way is to import only required methods from the library in our component. i.e

import orderBy from 'lodash/orderBy';
import filter from 'lodash/filter';
orimport {filter, orderBy} from 'lodash';

Note - It is worth noting that mixing these 2 import styles will cause the net benifit to be negative. Basically, this will import the entire lodash + individual utilities twice.

Second way is to use lodash-webpack-plugin to remove unused methods of the library.

Remove unused JS using code splitting — Lazy/Suspense

Large react application will usually consist of many components, libraries, utility methods etc. Here, we need to give a little effort to try to load different parts of an application only when they are needed. If effort is not made for this, a single bundle of JavaScript will be exported to our users as soon as they load the first page.

So we can split the bundles to make sure this never happens. React.lazy method makes it easy to split the code in the react application on a component level using dynamic imports.

import React, { lazy, Suspense } from 'react';
import LoadPage from './components/LoadPage';
const GridComponent = lazy(() => import('./GridComponent'));const HomeComponent = () => (
<div>
<Suspense fallback={<LoadPage />}>
<GridComponent />
</Suspense>
</div>
)
export default HomeComponent;

The React.lazy function provides a built-in way to separate components in the application. The separated components are then in form of separate chunks of JavaScript with very little effort. We can then take care of loading states when we couple it with the suspense component.

Enable compression - Gzip

One of the best ways to improve performance scoring is by compressing in the build process. using this, we can compress the build folder files by the package gzipper (npm install) and add this to the package.json.

"scripts": {
...
"build": "node scripts/build.js && gzipper compress ./build",
}

Using Gzip compression module can reduce your bundle size from 20% to 25%.

Additionally, we can also compress from the server-side. If we are using node.js to serve the build folder, we can use the compression package:

const compression = require('compression');
app.use(compression());

The techniques mentioned above really helped me to improve the performance score of my app. There are many more ways to optimize the performance of a React app. For example using service workers to cache application state, using useMemo, using virtualize long lists, avoiding unnecessary renders and many more.

Thanks for reading and hope you found this article helpful.

Originally published at https://codersread.com

Geek Culture