Home > database >  Updating component on mouseMove event very slow
Updating component on mouseMove event very slow

Time:08-11

I'm working on a project where I've got a div that is having it's location update with onm ouseMove events of it's parent. The code below shows how I'm doing it:

function Area () {
   const [mousePos, setMousePos] = useState({ x: 0, y: 0, })
   const handleMouseMove = event => {
      setMousePos({ 
         x: event.clientX - event.currentTarget.offsetLeft,
         y: event.clientY - event.currentTarget.offsetTop,
      })
   }
   const getStyle = () => { top: mousePos.y, left: mousePos.x, };
   return(
      <div className='main-area' onm ouseMove={handleMouseMove}>
         <div style={getStyle()}></div>
      </div>
   );
}

There are some css rules that help with the positioning etc. but I think they are irrelevant to the question (let me know if not?).

Anyway, my problem is that I'm getting really high CPU usage (~50% with intel i5-3570k) when moving my mouse inside the 'main-area' div, particularly when there are many other children components involved (not sure if this is because of event bubbling or the way the ReactDOM updates?). This is in the development build of react (I've not tried in production build).

Is this way of updating the position just inherently flawed and slow? Or is there a way to modify it slightly to make it faster?

Cheers

CodePudding user response:

I did some refactoring:

function Area () {
   const [mousePosX, setMousePosX] = useState(0);
   const [mousePosY, setMousePosY] = useState(0);
   const handleMouseMove = event => {
      setMousePosX(event.clientX - event.currentTarget.offsetLeft)
      setMousePosY(event.clientY - event.currentTarget.offsetTop)
   }
   return(
      <div className='main-area' onm ouseMove={handleMouseMove}>
         <div style={{top: mousePosY, left: mousePosX}}></div>
      </div>
   );
}

Can you check if the performance is better?

CodePudding user response:

I think this might be what you are looking for...

The remove event listener should remove the event listeners and prevent them from building up and causing the lag. Another sign you may need to add this remove event listener is if you're console in the browser tells you that you have exceeded the event limiter capacity.

const Area = () => {
    
    const [mousePosX, setMousePosX] = useState(0);
    const [mousePosY, setMousePosY] = useState(0);

    const handleMouseMove = (event) => {
        setMousePosY(event.clientY - event.currentTarget.offsetTop); 
        setMousePosX(event.clientX - event.currentTarget.offsetTop);
        return window.removeEventListener('mousemove', handleMouseMove);
        //return remove listener here ^
    }

    return(
       <div className='main-area' onm ouseMove={handleMouseMove}>
          <div style={{top: mousePosY, left: mousePosX}}></div>
       </div>
    );
 }

If this doesn't work you could also try putting the remove event listener in a useEffect with handleMouseMove as the dependency

  • Related