What is performance in React world?
What affects performance?
How do measure performance?
Example of bad performance.
What are the consequences of bad performance?
How to automate performance checks?
# ⚡Performance best practices
## Table of contents
- [Definition](#Definition)
- [Web performance](#Web-performance)
- [React performance](#React-performance)
- [Optimize React Performance](#react-performance)
- [Wasted rendering](#Wasted-rendering)
- [Large bundles](#Large-bundles)
- [Expensive operations](#Expensive-operations)
- [Tools and metrics](#Tools-and-metrics)
- [React profiler](#React-profiler-link)
- [Light house](#Light-house-link)
- [Consulted links](#Consulted-links)
## Definition
Watching the following course is strongly recomended as it has al
### Web performance
Web performance is all about making web sites fast, including making slow processes seem fast. Does the site load quickly? Does it allow the user to start interacting with it quickly? Does it offer reassuring feedback if something is taking time to load (e.g. a loading spinner)? Are scrolling and animations smooth?
### React performance
React performance is all about minimizing the number and size of costly DOM operations required to update the UI (e.g. rendering, bundles and operations)
## Optimize React Performance
>Opinion: premature optimization is a waste of energy. By default React has a good performance, optimization should be done when we have code. That way effort is made in better way.
### Wasted rendering
> Wasted rendering is when react renders and there is no change in the UI
#### React memo
Child components are rendered every time the parent renders. In order to avoid a child re-rendering if it's not supposed to, we have to wrap it in [React memo](https://es.reactjs.org/docs/react-api.html#reactmemo)
>React memo only exists as a **performance optimization** tool. Do not rely on it to “prevent” a render, as this can lead to bugs.
``` jsx
// Child renders every time Parent does
import React from 'react';
const Child = () => (<h1>Heavy component</h1>);
const Parent = () => (
<div>
Print Child
<Child />
</div>
);
```
``` jsx
// Child renders once
import React from 'react';
const Child = React.memo(() => (<h1>Heavy component</h1>));
const Parent = () => (
<div>
Print Child
<Child />
</div>
);
```
By default React memo will only shallowly compare complex objects in the props object. If you want control over the comparison, you can also provide a custom comparison function as the second argument.
#### React useCallback
>Useful when passing callbacks to optimized child components that rely on reference equality to prevent unnecessary renders.
When a function is passed as a parameter to the children and the parent Component renders, the function is redeclared even if its dependencies haven't changed. To avoid that, memoize the callback function using React useCallback
```jsx
import React from 'react';
const memoizedCallback = React.useCallback(
() => {
doSomething(a, b);
},
[a, b],
);
```
#### Overlayed states
happens when a component uses both an external state and an internal state that have the same information. as there's two states that changes the component renders twice.
To avoid the extra rendering, use external state directly
##### example
With react profiler and debug battery components from rater-meetingroom, we can now look at a wasted rendering.
You can identify wasted renderings looking at how many commits/rendering were done per change in the app, in this case when switched the battery level, which only changes the number on the component make two renders as seen at the highlighted section, meaning that there's a render that does nothing.

the issue is cused because the component has an internal state, which has an effect to change the external state. So it renders on both internal and external state change .

the solution is then to remove the internal state at the component, as it has the same info and use the external state directly

as seen now the action triggers one commit/render saving us 2.2ms in on every user interaction.

### Large bundles
> If you’re benchmarking or experiencing performance problems in your React apps, make sure you’re testing with the minified production build. As the development build is larger and slower due to development tools added to debug.
In some cases, if the users don't use expensive resources, they can be loaded on demand to avoid one large bundle using [react lazy](https://reactjs.org/docs/code-splitting.html#reactlazy).
A good place to start code spliting without disrupting the user experience is routes.
```jsx
import React from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
const Home = React.lazy(() => import('./routes/Home'));
const About = React.lazy(() => import('./routes/About'));
const App = () => (
<BrowserRouter>
<React.Suspense fallback={<div>Loading...</div>}>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</React.Suspense>
</BrowserRouter>
);
```
>React.lazy currently only supports default exports.
### Expensive operations
Sometimes a component is doing some expensive calculation everytime it renders, in those cases it is recommended for the Component to remember a value based on the parameters in which the usage depends on [React useMemo](https://en.reactjs.org/docs/hooks-reference.html#usememo)
```jsx
import React from 'react';
const memoizedValue = React.useMemo(() => computeExpensiveValue(a, b), [a, b]);
```
#### Example [(PR)](https://cronosccs.visualstudio.com/Tech%20Services/_git/Tech%20Services/pullrequest/3928)
Using react profiler we can take a look at the colors of the components, an the ones that are taking too much while rendering relative to others are going to be on yellow

the image above shows that in simple rendering of rater-meetingroom project the participant battery and user battery components are taking too much in relation to the others.

we can see that both components have the following function that is expensive because it iterates a hundred times, the solution is memoize it.

Now as you can see Battery compponents are not the ones that take longer, before Participant battery took 0,6ms to render, now 0,2ms. That gives us a total gain of 0,8 ms per render.

## Tools and metrics
> There's a bunch of tools online to measure and improve performance. We are not going to be able to cover all, that's why we are going to focus in the recomended one from react and some others.
### React profiler [(link)](https://reactjs.org/blog/2018/09/10/introducing-the-react-profiler.html)
Is a specific tool that comes with the Ract dev tools extension for browsers, it allows you to identify how the app and components inside it are being rendered and how much did they take to do so.
This allows us to identify wasted renderings and expensive componets that are making our app to not be performant.

*Rater workflow app*
### Light house [(link)](https://developers.google.com/web/tools/lighthouse?hl=en)
An open source tool to enhance quality on web apps, it has a lot of features but the one we care about is the performance metrics it extract from the analized desired web app.

*Rater workflow app*
## Consulted links
- [Mozilla - What's web performance](https://developer.mozilla.org/en-US/docs/Learn/Performance/What_is_web_performance)
- [Mozilla - Measuring performance](https://developer.mozilla.org/en-US/docs/Learn/Performance/Measuring_performance)
- [Pluralsight - Optimize Performance for React](https://app.pluralsight.com/library/courses/optimize-performance-react/table-of-contents)
- [React - Optimizing performance](https://reactjs.org/docs/optimizing-performance.html#gatsby-focus-wrapper)
- [React - Dev tools](https://es.reactjs.org/blog/2015/09/02/new-react-developer-tools.html)
- [React - Profiler](https://reactjs.org/blog/2018/09/10/introducing-the-react-profiler.html)
- [Google - Light house](https://developers.google.com/web/tools/lighthouse?hl=en)