Top 7 Libraries for Blazingly Fast ReactJS Applications

Mohammad Faisal - Aug 18 '23 - - Dev Community

To read more articles like this, visit my blog

ReactJS is very performant by default. But now and then, you get a chance to make it even better. And the incredible React community has come up with some fantastic libraries.

Today we will talk about seven such libraries that can improve the quality of your code and, at the same time, improve performance.

Let’s begin.

1. React Query

React Query is known to be the missing state management library for React. In its documentation, it says, “Fetch, cache, and update data in your React applications all without touching any ‘global state’.”

Yes. This is precisely what it does. It helps us to manage the server state without any hassle. It can reduce the necessity for using a state management library like Redux.

Advantages

  • Automatic caching

  • Updates data automatically in the background

  • Reduces code by a lot

Before React Query

Here is an example hook to fetch data using our own custom hook. It doesn't even support caching.

const useFetch = (url) => {
  const [data, setData] = useState();
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState(false);

  useEffect(() => {
    const fetchData = async () => {
      setIsError(false);
      setIsLoading(true);
      try {
        const result = await fetch(url);
        setData(result.data);
      } catch (error) {
        setError(error);
      }
      setIsLoading(false);
    };
    fetchData();
  }, [url]);

  return {data , isLoading , isError}
}
Enter fullscreen mode Exit fullscreen mode

After React Query

Here is the code if we want to use React Query. Look how small it is.

import { useQuery } from 'react-query'

const { isLoading, error, data } = useQuery('repoData', () =>
    fetch(url).then(res =>res.json()
  )
)
Enter fullscreen mode Exit fullscreen mode

Look how much it reduced our code.

2. React Hook Form

React Hook Form is the modern form-handling library that can take your form's performance to a new level.

Advantages

  • Reduces code

  • Reduces unnecessary re-rendering

  • Easily integrates with modern UI libraries

Following is an example demonstrating how React Hook Form can improve code quality.

Without React Hook Form

Here is an example of building a login form manually.

function LoginForm() {
  const [email, setEmail] = React.useState("");
  const [password, setPassword] = React.useState("");

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    console.log({email, password});
  }

  return (
    <form onSubmit={handleSubmit}>

      <input
        type="email"
        id="email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
      />

      <input
        type="password"
        id="password"
        value={password}
        onChange={(e) => setPassword(e.target.value)}
      />

    </form>
  );
}
Enter fullscreen mode Exit fullscreen mode

With React Form

Here is the same example with React Hook Form.

function LoginForm() {
  const { register, handleSubmit } = useForm();

  const onSubmit = data => console.log(data);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register("email")} />
      <input {...register("password")} />
      <input type="submit" />
    </form>
  );
}
Enter fullscreen mode Exit fullscreen mode

It’s so clean and, at the same time, performant. Give it a try.

3. React Window

React Window is used to render long lists. Imagine you have a list of 1,000 items. Only ten are visible simultaneously, but your code tries to render all 1,000 items simultaneously.

This can cause serious studdering in your application. This is a very popular library and a must-have tool in your arsenal.

Manual rendering of 1,000 items

import React, {useEffect, useState} from 'react';

const names = [] // 1000 names

export const LongList = () => {

    return <div> 
      {names.map(name => <div> Name is: {name} </div>)} 
    <div/>
}
Enter fullscreen mode Exit fullscreen mode

But this code renders 1,000 items simultaneously, although you can see at most ten–20 items on your screen.

Using React Window

Now let’s use React Window.

import { FixedSizeList as List } from 'react-window';

const Row = ({ index, style }) => <div style={style}> Name is {names[index]}</div>

const LongList = () => (
  <List
    height={150}
    itemCount={1000}
    itemSize={35}
    width={300}
  >
    {Row}
  </List>
);
Enter fullscreen mode Exit fullscreen mode

This code renders only what you see on the screen. It can be intimidating initially but necessary if you have a long list to render.

4. React LazyLoad

Lazy loading is a technique used to load only what you need. Thus it improves performance by not overusing computation power.

React LazyLoad is a library specifically built for that purpose. You just wrap your component, and this library takes care of the rest.

Advantages

  • Improved performance

  • Supports server-side rendering

Without LazyLoad

Here is an example where we are loading five images manually.

import React from 'react';

const ImageList = () => {

  return <div>
    <img src ='image1.png' />
    <img src ='image2.png' />
    <img src ='image3.png' />
    <img src ='image4.png' />
    <img src ='image5.png' />
  </div>
}
Enter fullscreen mode Exit fullscreen mode

With LazyLoad

Here is the same example with the LazyLoad component.

import React from 'react';
import LazyLoad from 'react-lazyload';


const ImageList = () => {

  return <div>
    <LazyLoad> <img src ='image1.png' /> <LazyLoad>
    <LazyLoad> <img src ='image2.png' /> <LazyLoad>
    <LazyLoad> <img src ='image3.png' /> <LazyLoad>
    <LazyLoad> <img src ='image4.png' /> <LazyLoad>
    <LazyLoad> <img src ='image5.png' /> <LazyLoad>
  </div>
}
Enter fullscreen mode Exit fullscreen mode

5. Why Did You Render

Unnecessary rendering can hurt the performance of your React applications performance. But sometimes, we do it without even knowing.

This awesome package, Why Did You Render, helps us to find performance issues and solve them. You just turn it on in any component, and it tells you exactly why it renders.

Following is a component with render issues.

import React, {useState} from 'react'

const WhyDidYouRenderDemo = () => {
    console.log('render')

    const [user , setUser] = useState({})
    const updateUser = () => setUser({name: 'faisal'})

    return <>
        <div > User is : {user.name}</div>
        <button onClick={updateUser}> Update </button>
    </>
}

export default WhyDidYouRenderDemo
Enter fullscreen mode Exit fullscreen mode

Once turned on, this library will console-log the following output.

Render Cause

This log shows that we are updating the object with the same value, which is terrible for performance.

6. Reselect

If you are using Redux, then this is a lifesaver. We know Redux reducers can store a lot of data, and if you feed the complete store into any component, it will cause it to re-render anytime anything in that store updates.

Reselect solves this problem by memorizing the values and only passing what’s necessary.

Advantages (from the documentation)

  • Selectors can compute derived data, allowing Redux to store the minimal possible state.

  • Selectors are efficient. A selector is not recomputed unless one of its arguments changes.

  • Selectors are compostable. They can be used as input to other selectors.

Example

Following is an example of bringing the values from inside the store and modifying them in a selector.

import { createSelector } from 'reselect'

const shopItemsSelector = state => state.shop.items

const subtotalSelector = createSelector(
  shopItemsSelector,
  items => items.reduce((subtotal, item) => subtotal + item.value, 0)
)

const exampleState = {
  shop: {
    items: [
      { name: 'apple', value: 1.20 },
      { name: 'orange', value: 0.95 },
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

7. Deep Equal

Deep Equal is a famous library that can be used to compare. This is handy. After all, in JavaScript, although two objects can have the same values, they are considered different because they point to different memory locations.

That’s why we see the following kind of result.

const user1 = {
    name:'faisal'
}
const user2 ={
    name:'faisal'
}

const normalEqual = user1 === user2 // false
Enter fullscreen mode Exit fullscreen mode

But if you need to check for equality (for memoization), it becomes a costly (and complex) operation.

If we use Deep Equal, then it improves performance by** 46 times. **Below is an example of how we can use it.

var equal = require('deep-equal');

const user1 = {
    name:'faisal'
}
const user2 ={
    name:'faisal'
}

const deepEqual = equal(user1 , user2); // true -> exactly what we wanted!
Enter fullscreen mode Exit fullscreen mode

There you go. These are some of the most important libraries you can use to maximize the performance of your React application.

Leave a comment if you have some other ones in mind. Have a great day!

Have something to say? Get in touch with me via LinkedIn or Personal Website

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .