DEV Community

Cover image for 5 ways to make React app super fast 🚀
Tirth Patel
Tirth Patel

Posted on

5 ways to make React app super fast 🚀

Are you struggling to make your gigantic react app more efficient in terms of Performance?

Don't worry! You've landed at the right location. These 5 methods will make your slow 🐢 React app into a fast app 🐇.

For busy readers, here are the 5 methods in a nutshell.

  1. use callback
  2. useMemo
  3. memoized components
  4. Components Lazy import
  5. Image Lazy loading

1. useCallback

  • When you declare a normal component, it runs each time when your component renders.
  • Instead of declaring a normal function in the component, wrap it with useCallback.
  • useCallback is a React hook that gives you a cached function. It is cached until any of its dependencies are changed.
  • This way you get 2 benefits. 1) On change of any of its dependencies you get a fresh function respective to that value. 2) Unnecessary function calls are reduced which in turn increases the app's performance.
  • Have a look at these basic conversions from normal functions to the useCallback function.
export const MyProfile: React.FC = (props) => {
  const {birthYear, name} = props

  // normal function. this is called every time component renders
  const calculateAge = () => {
    const currentYear = new Date().getFullYear()  
    return currentYear - birthYear
  }

  // efficient function. this will be called only when dependencies will be changed
  const efficientCalculateAge = useCallback(() => {
    const currentYear = new Date().getFullYear()
    return currentYear - birthYear
  }, [birthYear])

  return (
    <Fragment>
      <p>Your Age : {efficientCalculateAge()}</p>
    </Fragment>
  )
}
Enter fullscreen mode Exit fullscreen mode

2. useMemo

  • Typically in a React component, there are more variables than functions.
  • Above we mentioned to cache functions. How if we can cache variables also? 🤔
  • Here useMemo enters your game. Just do all the computation stuff and store the value wrapped with useMemo.
  • Benefits of useMemo are the same as useCallback. Just the difference would be useMemo will return a variable while useCallback will return a function.
  • Here is how you can simply implement useMemo in your project.
export const MyCart: React.FC = (props) => {
  const {cartList} = props

  // this will be re-evaluated on every render
  const totalAmount = cartList.reduce((acc, item) => {
    return acc + item.price
  }, 0)

  // this will be re-evaluated only when cartList changes
  const efficientTotalAmount = useCallback(() => {
    return cartList.reduce((acc, item) => {
      return acc + item.price
    }, 0)
  }, [cartList])

  return (
        <Fragment>
            <p>Total cart amount : {efficientTotalAmount}</p>
        </Fragment>
    )
}
Enter fullscreen mode Exit fullscreen mode

3. memoized Components

  • Suppose you have Profile component. It includes 5 children components. So you might have noticed that even if the props of one child component have changed, all 5 will re-render. Have you thought WHY?
  • It is because other children's components are not memoized.
  • Technically we can understand a memo as It lets you skip re-rendering a component when its props are unchanged.
  • It is also a kind of caching. Caching of components. Here when the parent component re-renders, it rerenders all of its children. React also does that. But if the component is memoized, React will return the unchanged cached copy of the component. This will eventually same computation time and in return, we'll get SPEED.⚡
export const MyProfile: React.FC = (props) => {
  const {userId} = props
  const [cartList, setCartList] = useState([])

  const getCartListData =useCallback(async (userId:number) => {
    return await fetch(`https://jsonplaceholder.typicode.com/users/${userId}`)
  },[])

  useEffect(() => {
    getCartListData(userId).then((data) => {
      setCartList(data)
    })
  }, [userId])

  // MyCart component will be re-rendered only when cartList changes
  return (
    <Fragment>
      <MyCart cartList={cartList} />
    </Fragment>
  )
}


export const MyCart: React.FC = memo((props) => {
  const {cartList} = props

  // this will be re-evaluated on every render
  const totalAmount = cartList.reduce((acc, item) => {
    return acc + item.price
  }, 0)

  // this will be re-evaluated only when cartList changes
  const efficientTotalAmount = useCallback(() => {
    return cartList.reduce((acc, item) => {
      return acc + item.price
    }, 0)
  }, [cartList])

  return (
        <Fragment>
            <p>Total cart amount : {efficientTotalAmount}</p>
        </Fragment>
    )
})
Enter fullscreen mode Exit fullscreen mode

4. Lazy imports of components

  • Making a gigantic app includes hundreds of components. Some small, some big.
  • To load all heavy (in terms of computation) components in one go will surely impact the app's startup time.
  • Wise approach would be to dynamically import the components as and when required. We also call it Lazy Loading.
  • Suppose there is a component called <CropImage />. It has some heavy libraries used in it. We can lazily load it when the user wants to open that.
import React, {Fragment} from 'react'

// importing CropImage as a lazy component
const CropImage = React.lazy(() => import('./CropImage'))


export const MyProfile: React.FC = (props) => {
  // Using React.lazy and Suspense we can import the component only when it is needed
  const CropImageComponent = () => {
    return (
      <Suspense fallback={<div>Loading...</div>}>
        <CropImage />
      </Suspense>
    )
  }

  return (
    <Fragment>
      <CropImageComponent />
    </Fragment>
  )
}
Enter fullscreen mode Exit fullscreen mode

5. Lazy loading images

  • Suppose any app requires 500 images in the entire project. If we load all 500 images at once, that will lead to heavy computation on the client side. (Internet required to load images etc)
  • In this case, I would suggest lazily load images. Only when the user comes to the respective component where that image is required, the only image is loaded not at the start of the app.
  • react-lazyload and react-image-lazy are some of the libraries which can make this happen.

Lazy load image
Source : react-lazy-load-image-component


Key takeaways 📝

  • You shall use React hooks like useCallback and useMemo to take benefit of cached variables/functions. And get the latest update value whenever any of the dependencies are modified.
  • Lazy loading gigantic and complex components is a wise choice, especially for a scalable app trying to improvise a performance.
  • Assets such as images, videos, etc can also be used lazily as required.

Closing comments 🙋‍♂️

  • Thank you for reading along with me. If you find any queries on the topic mentioned above, please ping me in the comments. 💬
  • Knowledge spreads by sharing. So please share this article with your concerned friends. 📱
  • PS: Also, I humbly request you to write which topic you want in my next blog. I will include that in my target list. 🎯

Tirth Patel, signing off!🫡

Top comments (0)