React Performance

Tools to measure React performance

If you’re benchmarking or seeing performance problems in your React apps, make sure you’re testing with the minified production build. The development build includes extra warnings that are helpful when building your apps, but it is slower due to the extra bookkeeping it does. Also, a good point is disabling chrome extensions, especially React DevTools. They can significantly skew the results.

Tools:

  • Profiling Components with the Chrome Performance Tab (only in dev mode)

    1. Open the Chrome DevTools Performance tab and press Record.

    2. Perform the actions you want to profile. Don’t record more than 20 seconds or Chrome might hang.

    3. Stop recording.

    4. React events will be grouped under the User Timing label.

  • Profiling Components with the DevTools Profiler (for dev mode, but can be enabled in production also) This plugin uses React’s experimental Profiler API to collect timing information about each component that’s rendered in order to identify performance bottlenecks in React applications. Once you’ve started recording, DevTools will automatically collect performance information each time your application renders. Use your app as you normally would. When you are finished profiling, click the “Stop” button.

  • Using React's Profiler API (The Profiler component lets you measure just what you're interested in. Being able to access the performance data in your application code gives you full control over what you want to do with it.)

  • why-did-you-render (for dev mode) lib for React to notify you about avoidable re-renders.

Ways to improve React performance

  • useMemo() This is a React hook that is used to cache functions in React, CPU-expensive functions.

  • useCallback() This works as useMemo but the difference is that it’s used to memoize function declarations.

  • Caching functions Functions can be called in the React component JSX in the render method. If the functions get expensive, ie it takes long to execute it will hang the rest of the re-render code to finish thereby hampering the user’s experience. Such functions should be cached

  • shouldComponentUpdate() shouldComponentUpdate is called whenever the component is being re-rendered, if it returns true then the component is re-rendered, if false the re-rendering is canceled. This method accepts the next state object and next props object as an argument, so with this, we will implement our check to tell React when we wnt to re-render

  • React.PureComponent React.PureComponent is a base component class that checks the fields of state and props to know whether the component should be updated. It shallowly compares the fields of the previous props and state objects with the fields of the next props and state objects. It doesn’t just do the object reference comparison of them. React.PureComponent optimizes our components by reducing the number of wasted renders.

  • React.memo() Just like useMemo and React.PureComponent, React.memo() is used to memoize/cache functional components

  • Virtualize long lists If you render large lists of data, it is recommended that you render only a small portion of the datasets at a time within the visible viewport of a browser, then the next data are rendered as the lists is scrolled, this is called “windowing”. (there are libs for that react-window and react-virtuaized).

  • Using reselect selectors Using reselect optimizes our Redux state management. As Redux practices immutability that means new object references will be created every time on action dispatch. This will hamper performance because re-render will be triggered on components even when the object references change but the fields haven’t changed. Reselect library encapsulates the Redux state and checks the fields of the state and tells React when to render or not if the fields haven’t changed.

  • Web worker JS code runs on a single thread. Running a long process on the same thread will seriously affect the UI-rendering code, so the best bet is to move the process to another thread. This is done by Web workers. They are the gateway where we can create a thread and run it parallel to the main thread without hampering the UI-flow.

  • Lazy loading The React.lazy function lets you render a dynamic import as a regular component. The callback function of the React.lazy returns a Promise via the import() call. The Promise resolves if the module loads successfully and rejects if there was an error in loading the module, due to network failure, wrong path resolution, no file found. When webpack walks through our code to compile and bundle, it creates a separate bundle when it hits the React.lazy() and import().

Last updated

Was this helpful?