Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Performance issue with very fast setState calls in React?

Tags:

reactjs

I've created a simple draggable component. I'm using the react-swipeable library but my question is about any event which repeatedly and in quick succession updates useState.

With the console.log in onSwiping I can see that the function is called many times per second, which is what I need to update the position of the component. This works however is there a performance issue with calling setSwipeX so frequently?

The entire component will re-render very fast as it's dragged. Is this OK or would it be better to just update swipeX without re-rendering the entire component, and is this even possible?

import React from "react";
import { useSwipeable } from "react-swipeable";

export default function App() {
  const [swipeX, setSwipeX] = React.useState(0);

  const swipeHandlers = useSwipeable({
    onSwiping: (e) => {
      console.log(e);
      setSwipeX(-e.deltaX);
    },
    trackMouse: true
  });

  return (
    <div
      className="App"
      {...swipeHandlers}
      style={{
        transform: `translateX(${swipeX}px)`
      }}
    >
      <h1>Stuff</h1>
    </div>
  );
}

https://codesandbox.io/s/relaxed-minsky-ni7n9?file=/src/App.js

like image 779
Evanss Avatar asked Sep 03 '20 10:09

Evanss


People also ask

What makes Reactjs performance faster?

To optimize React rendering, you need to make sure that components receive only necessary props. It will let you control the CPU consumption and avoid over-rendering unnecessary features. The solution is to create a functional component that will collect all props and redistribute them to other components.

How do I stop Rerendering in React?

1. Memoization using useMemo() and UseCallback() Hooks. Memoization enables your code to re-render components only if there's a change in the props. With this technique, developers can avoid unnecessary renderings and reduce the computational load in applications.

How do you lower the load time on React app?

To solve this react itself has a native solution, which is code-splitting and lazy loading. Which allows splitting bundle files into a smaller size. The best place to introduce code splitting is in routes. Route-based code splitting solve half of the issues.


1 Answers

I'm not an expert when it comes to performance, but I have implemented a couple of weeks ago a component that lets you swipe down page component. It was very similar to what you were doing, but vertically. First time I tried to do so with useState, I had no issues on my Pixel 3a. But when I tested it on Nexus 5x, it wasn't smooth at all. When I changed the logic to work with useRef instead of userState, it felt much smoother. Something like this:

import React from "react";
import { useSwipeable } from "react-swipeable";

export default function App() {
  const ref = React.useRef(null);

  const swipeHandlers = useSwipeable({
    onSwiping: (e) => {
      console.log(e);
      ref.style.transform = `translateX(${-e.deltaX}px)`;
    },
    trackMouse: true
  });

  return (
    <div
      className="App"
      {...swipeHandlers}
      ref={ref}
    >
      <h1>Stuff</h1>
    </div>
  );
}

This way, you change the DOM directly. As mentioned again, I didn't test it by numbers, but physically on a low end device I could see a bit of difference.

like image 131
Eliya Cohen Avatar answered Nov 03 '22 04:11

Eliya Cohen