The tribulations of React performance optimizations 
Tags: react, performance, usememo, usecallback
Published: 2020-10-13 08:51:33

As I see it occuring so many times in the industry, it so happens that many developers do anticipate performance issues while still in early development stages of an application project. 

And this, even prior to running the app on a production-like environment ! 

This strategy often ends up being the same as shooting oneself in the foot.

**Why you say? Because optimizations always come with a cost!**

## Use case: code-splitting

> Is spreading the total loading time of the app always a good idea? Is splitting the code and lazy-loading the different chunks, always a good solution? Every time? No matter what?

Well:

  - Are those chunks really heavy enough to justify having the [_spinning wheel of death_](https://www.businessinsider.fr/us/how-to-stop-spinning-wheel-on-mac) appear everytime the user clicks on a link?
  - Or should you rather have an app displaying a longer intial loading time but which, once fully loaded and cached, responds swiftly to all user interactions?
  - Are your end users from the general public, or are they B2B customers? Sure users in general don't like to wait of course, nobody does, however:
      - B2B users might not have a choice than to be using your app, so if there is no budget for optimization, then intial loading time can be "_imposed_" upon them with minimal business repercussions;
      - On the other hand, public users, C2B users, WILL go away and shop somewhere else if your e-commerce app takes too long to load, having a real impact on business revenue in the short or medium term

## What to look out for

- After a hard reload, meaning you got rid of all cached elements, and after applying a given optimization, is the app starting faster during its initial render?  
- Is this really the only criteria to consider ?
- What are you trying to achieve?
  - Do you want users to feel that your app loads fast? 
  - Do you want the app to respond quickly to user interaction? 

**Sure! We all want both, but again, at what cost?**

But most importantly : 

- does it depend only on what YOU want or think as a developer ?  
- what if the target machine is a smartphone, can you afford to have many http requests, knowing how it impacts battery life ?
- what if there is no budget for optimization ?
- what is the hosting plan in production, and what is the cost related to hitting your server by an increased amount of http requests ?

## So what is the solution? 

We must be able to evaluate the cost of the optimization by clearly identifying what was lost and what was gained. 

**It's all about the tradeoffs baby!**

### Step #1 - Diagnose

So, let's first run the app we are working on, and IF we find that the app starts too slowly, or a certain component takes too much time to mount or render, THEN let's diagnose the problem.

**How?** 
- The [React devtools Profiler](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi) or the [React Profiler API](https://reactjs.org/docs/profiler.html#usage) are examples of a tools which might help identifying long re-rendering times.
- The [network devtools](https://developers.google.com/web/tools/chrome-devtools/network) might also help identifying heavy JS or CSS resources.
- The build report provided by the [create-react-app build script](https://create-react-app.dev/docs/production-build) also provides a list of chunks along with their gzip file size 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/xhwfjnq8h4xbzugzsqrg.png)

- And let's not forget the almighty [Lighthouse](https://developers.google.com/web/tools/lighthouse), another one of the Chrome devtools.

### Step #2 - Measure

So let's measure the problem. 

- How much time do components take to mount or render? 
- How much time is a function taking to run ? 
- Is there some JS or CSS resource blocking the intial app rendering ?

Check out [Progressive React](https://houssein.me/progressive-react) for details on measuring using different tools.

### Step #3 - Identify & Apply optimization

After diagnosis and measurement, the right optimization strategy should form.  This allows to identify the appropriate optimization technique(s) for the particular situation we're trying to solve. So, here's when we apply an initial solution.

### Step #4 - Measure again & Compare

Lastly, let's measure once again to ensure that the optimization cost was worthwhile.

**How?** By comparing the new measure to the original measure, the one we took while diagnosing the problem.

## Conclusions

All in all, these are examples *only* of considerations to take into account even *before* we start optimizing just for the sake of it.

The right optimization strategy is far from being a "simple"  *technical-only* subject, and depends *at least* on: 

1) budget,
2) the nature of the app,
3) end users (& stakeholders at large),
4) the end users' target machines
5) technical requirements of the production environment

## Final words of caution about optimization in general

So, let's not [optimize](https://reactjs.org/docs/optimizing-performance.html#profiling-components-with-the-devtools-profiler) for the sake of it.

Meaning, let's not memoize or avoid inline objects systematically ([`React.useMemo`](https://reactjs.org/docs/hooks-reference.html#usememo) & [`React.useCallback`](https://reactjs.org/docs/hooks-reference.html#usecallback)).

Let's not split our code and lazy load it systematically ([`React.lazy` + `React.Suspense` + `Spinner` + `ErroBoundary`](https://reactjs.org/docs/code-splitting.html)).

Let's not memoize components systematically ([`React.memo`](https://reactjs.org/docs/react-api.html#reactmemo), [`React.PureComponent`](https://reactjs.org/docs/react-api.html#reactpurecomponent), [`shouldComponentUpdate`](https://reactjs.org/docs/react-component.html#shouldcomponentupdate)).

### In order words: consider the act of optimizing ONLY if there is a performance problem or complaint in production!

---

## Bonus: Recommended Toolchains

The React team primarily recommends these solutions:

- If you’re **learning React** or **creating a new [single-page app](https://reactjs.org/docs/glossary.html#single-page-application)**, use [Create React App](https://github.com/facebook/create-react-app).
- If you’re building a **server-rendered website with Node.js**, try [Next.js](https://nextjs.org/).
- If you’re building a **static content-oriented website**, try [Gatsby](https://www.gatsbyjs.com/).
- If you’re building a **component library** or **integrating with an existing codebase**, try [More Flexible Toolchains](https://reactjs.org/docs/create-a-new-react-app.html#more-flexible-toolchains).