Uncovering Hidden Performance Issues in React Apps
The Speed Trap
React’s incredible speed can sometimes be a double-edged sword. With powerful machines and fast internet connections, developers may overlook performance issues that can significantly impact users. But what happens when our users access our web apps on mid-tier mobile smartphones with slow internet connections? The consequences can be devastating, leading to poor conversion rates and a negative user experience.
Reproducing the Problem
To demonstrate this issue, let’s create a sandbox with a performance problem caused by a common React anti-pattern. Our app simulates a header that changes size as the user scrolls, with a list of many rows representing a medium-to-large application. To reproduce the issue on powerful machines, we can artificially slow down the browser by throttling the CPU using Chrome’s Performance tab.
Detecting the Bug
The usual approach to identifying the issue involves using React or Browser dev-tools. However, let’s take a different route by utilizing the Why Did You Render library. This powerful tool detects why a component is re-rendering and provides valuable insights into potentially avoidable re-renders.
Why Did You Render?
Why Did You Render is a library created by Welldone Software that helps developers identify performance issues in their React apps. By adding the library to our project, we can gain a deeper understanding of why our components are re-rendering. Note that this library should only be used during debugging, as it can slow down React and cause issues in certain edge cases.
import { whyDidYouRender } from '@welldone-software/why-did-you-render';
whyDidYouRender(React, {
// Enable the profiler
profiler: true,
});
Uncovering the Root Cause
With Why Did You Render installed, we can see that the Main component re-renders on every scroll event, causing janks in the application. The library reveals that the style prop is the culprit, receiving different objects that are equal by value. This leads us to the App.js file, where we discover that the useHeaderScroll hook causes App to re-render, triggering the Main element to be re-created.
const App = () => {
const { scrollTop } = useHeaderScroll();
return (
<Main style={{ height: `${scrollTop}px` }}>
{/* content */}
</Main>
);
};
Solving the Problem
The solution lies in passing only the relevant value to Main instead of the style object. By making this simple change, we can prevent Main from re-rendering unnecessarily.
const App = () => {
const { scrollTop } = useHeaderScroll();
return (
<Main scrollTop={scrollTop}>
{/* content */}
</Main>
);
};
The Power of Why Did You Render
Using Why Did You Render can significantly improve the performance of your React app by identifying hidden issues. Its detailed reports provide valuable insights, allowing you to optimize your app’s speed and conversion rates. Try running your initial page load with Why Did You Render to see how you can speed up your app in minutes.
- Identify performance bottlenecks: Why Did You Render helps you detect unnecessary re-renders and optimize your app’s performance.
- Improve conversion rates: By identifying and fixing performance issues, you can improve your app’s speed and conversion rates.
- Learn more about Why Did You Render