DEV Community

Cover image for React Batching and how it can make your page faster
Ary Barros
Ary Barros

Posted on

React Batching and how it can make your page faster

From new to more experienced developers, they know that the biggest challenge with a React page is its quantity of rendering. The smaller, the faster your application will be and the more effective your user's feedback on the generated page will be.

In React, both hooks and changing a state can generate a new rendering on the page, which depending on its size, can take a few milliseconds crucial for the user experience. Let's look at a practical example:

setTimeout(() => {
  setCount(c => c + 1);
  setFlag(f => !f);
}, 1000);
Enter fullscreen mode Exit fullscreen mode

In the example above, React renders the same component twice (depending on the prop structure, the page renders as well). By default, every setState that is locked in promises, async awaits and timeouts will be rendered unitarily.

This behavior also happens when we have async await calls in code that render a series of states in a row. Let's see the example below:

  const [name, setName] = useState('');
  const [lastName, setLastName] = useState('');
  const [phone, setPhone] = useState('');

  const handleClickAsync = async () => {
    await setName('Ary');
    setLastName('Barros');
    setPhone('+5584999828379');
  }
Enter fullscreen mode Exit fullscreen mode

This is a very common code when we want to call an API in useEffect and we use an asynchronous function to get the data. In the above function, every time we have an async block in the code, React will render every state change, in this case, rendering 3 times in a row unnecessarily.

So how can we get rid of the render loop? Through the concept of Batching.

Batching is the act of grouping tasks together, so you do them all at once, instead of switching between tasks that take place in different programs or areas. - Kelsey Jones

Forcing batching in React applications

ReactDOM, a library that works with React, has the unstable_batchedUpdates method in one of its features. With it, we can force a batch of a set of states, both inside and outside of async-await methods.

  const [name, setName] = useState('');
  const [lastName, setLastName] = useState('');
  const [phone, setPhone] = useState('');

  const handleClickAsync = async () => {
    ReactDOM.unstable_batchedUpdates(() => {
      await setName('Ary');
      setLastName('Barros');
      setPhone('+5584999828379');
    )};
  }
Enter fullscreen mode Exit fullscreen mode

Introducing Auto batching in React 18.0

New functionality in React 18.0 brought auto batching. In this case, any code blocks inside promises, async awaits and timeouts are now automatically batched to generate a single rendering and thus improve the performance of the page as a whole. Let's look at the official example from the React page:

// Before: only React events were batched.
setTimeout(() => {
  setCount(c => c + 1);
  setFlag(f => !f);
  // React will render twice, once for each state update (no batching)
}, 1000);

// After: updates inside of timeouts, promises,
// native event handlers or any other event are batched.
setTimeout(() => {
  setCount(c => c + 1);
  setFlag(f => !f);
  // React will only re-render once at the end (that's batching!)
}, 1000);
Enter fullscreen mode Exit fullscreen mode

So, we have two solutions, if your project can't upload the React version, use the unstable_batchedUpdates method. If there is the possibility of upgrading, always use the newest version of React and take advantage of the new features developed such as automatic batching.

Hope I helped you learn something new. See you next time.

Top comments (1)

Collapse
 
dineshwebdeveloper profile image
dineshwebdeveloper

As an experienced developer this is what something i am thriving to learn thanks for the nice article