Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Performance penalty of creating handlers on every render with react-hooks

I'm currently very amazed about the use cases of the new react hooks API and what you can possibly do with it.

A question that came up while experimenting was how expensive it is to always create a new handler function just to throw it away when using useCallback.

Considering this example:

const MyCounter = ({initial}) => {     const [count, setCount] = useState(initial);      const increase = useCallback(() => setCount(count => count + 1), [setCount]);     const decrease = useCallback(() => setCount(count => count > 0 ? count - 1 : 0), [setCount]);      return (         <div className="counter">             <p>The count is {count}.</p>             <button onClick={decrease} disabled={count === 0}> - </button>             <button onClick={increase}> + </button>         </div>     ); }; 

Although I'm wrapping the handler into a useCallback to avoid passing down a new handler every time it renders the inline arrow function still has to be created only to be thrown away in the majority of times.

Probably not a big deal if I only render a few components. But how big is the impact on performance if I do that 1000s of times? Is there a noticeable performance penalty? And what would be a way to avoid it? Probably a static handler factory that only gets called when a new handler has to be created?

like image 594
trixn Avatar asked Nov 16 '18 10:11

trixn


People also ask

Should I always use React hooks?

Instead, always use Hooks at the top level of your React function, before any early returns. By following this rule, you ensure that Hooks are called in the same order each time a component renders. That's what allows React to correctly preserve the state of Hooks between multiple useState and useEffect calls.

Are React hooks called every render?

Yes they are called on each render, in the first render it initialise a memory cell, on re-render it read the value of the current cell : When you call a Hook like useState(), it reads the current cell (or initializes it during the first render), and then moves the pointer to the next one.

Why do React hooks make use of refs?

Refs in React are incredibly useful for accessing and manipulating DOM elements directly. Refs are also amazing at persisting data between renders which is makes it possible to store persisted component data without causing a re-render when it is changed.


1 Answers

The React FAQs provide an explanation to it

Are Hooks slow because of creating functions in render?

No. In modern browsers, the raw performance of closures compared to classes doesn’t differ significantly except in extreme scenarios.

In addition, consider that the design of Hooks is more efficient in a couple ways:

Hooks avoid a lot of the overhead that classes require, like the cost of creating class instances and binding event handlers in the constructor.

Idiomatic code using Hooks doesn’t need the deep component tree nesting that is prevalent in codebases that use higher-order components, render props, and context. With smaller component trees, React has less work to do.

Traditionally, performance concerns around inline functions in React have been related to how passing new callbacks on each render breaks shouldComponentUpdate optimizations in child components. Hooks approach this problem from three sides.

So overall benefits that hooks provide are much greater than the penalty of creating new functions

Moreover for functional components, you can optimize by making use of useMemo so that the components are re-rendering when there is not change in their props.

like image 135
Shubham Khatri Avatar answered Sep 18 '22 15:09

Shubham Khatri