The demo below is a deliberately slow example from 2020.
Before digging deeper into what can create performance problems in your React application, please take note of the following:
- React is pretty fast by default, hence premature optimizations are not needed
- React performance is different than your custom components performance
- Measure production builds; development checks add overhead
Forms
Yep. Forms - let's check out some code that I intentionally made pretty unperformant. 👨💻
import React from "react";
import faker from "faker";
function Input({ onChange, value }) {
console.log("Input - rendered");
return <input type="text" onChange={onChange} value={value} />;
}
function DropdownItem() {
console.log("DropdownItem - rendered");
const option = faker.fake("{{hacker.verb}}");
return <option value={option}>{option}</option>;
}
function Dropdown() {
console.log("Dropdown - rendered");
const [selected, setSelected] = React.useState("");
return (
<select
value={selected}
onChange={({ target }) => setSelected(target.value)}
>
{[...Array(1000)].map((_, i) => (
<DropdownItem key={i} />
))}
</select>
);
}
function Form() {
const [inputVal, setInputVal] = React.useState("");
console.log("Form - rendered");
return (
<form>
<h1> Form </h1>
<Input
value={inputVal}
onChange={({ target }) => setInputVal(target.value)}
/>
<Dropdown />
</form>
);
}
export default function App() {
return (
<div className="App">
<Form />
</div>
);
}
We have the following components representation:
So, to render this - React created the following VDOM:
As we can see, Input is a controlled component that changes the Form state every time the user types anything.
So when Input changes, React is creating a new VDOM tree starting at the component where something changed state or props -> the Form component:
Now it will diff the previous VDOM (the green one) and it will see that the Input component needs to be changed in the real DOM. But also since each DropdownItem component is calling
faker.fake("{{hacker.verb}}")
to get a new option, React updates changed option values and text. The existing DOM nodes can be reused.
DropdownItem is an example of why you should try to keep components pure.
Key takeaway ✨
All our components have been computed to create the new Virtual DOM - including all our 1000 DropdownItems 😱. So if our own components code is slow and we combine that with the fact that we are rendering a big amout of those components at a high frequency (every time the user types something), then we can bring the VDOM to its knees pretty easily.
Just to emphasize:
In this example, updating Form renders its children again. Rendering and updating the DOM are separate steps.
React, as all other technologies, has benefits and tradeoffs that we need to carefully consider.
What to improve
Keep option data stable and move input state closer to the input. Profile before adding memoization.
If you like this article, chances are you will also enjoy what I post on Twitter. 🔥
More interesting reads:

Top comments (0)