pmndrs / use-gesture

👇Bread n butter utility for component-tied mouse/touch gestures in React and Vanilla Javascript.
https://use-gesture.netlify.app
MIT License
8.95k stars 307 forks source link

useDrag is noticeably less responsive than useMove using Firefox #581

Closed HeartofPhos closed 1 year ago

HeartofPhos commented 1 year ago

Describe the bug Dragging a div using useDrag appears to stutter compared to useMove, this happens while using Firefox but not Edge. The issue is not noticeable at 60hz, a high refresh rate display is required to reproduce the issue, it is easily noticeable at 120hz/240hz

The issue occurs regardless of whether react-spring spring being used.

Sandbox or Video Sandbox (updated) Video

Information:

Checklist:

dbismut commented 1 year ago

Unfortunately I only have a 60hz monitor at the moment. But the useMove code is broken, you should either setPointerCapture or attach events to the window.

HeartofPhos commented 1 year ago

Indeed, the sandbox was broken, I've updated it, I've also added a video recorded at 120hz but slowed down by 50% so that the difference is visible at 60hz

dbismut commented 1 year ago

Hi @HeartofPhos, finally had the time to look into this. Can you try the following sandbox?

https://stackblitz.com/edit/react-ts-wmbqww?file=App.tsx

I've removed react-spring to focus on the lib only. The red square uses the genuine useDrag from the library while the green square uses a simplified implementation of useDrag.

HeartofPhos commented 1 year ago

Hi @HeartofPhos, finally had the time to look into this. Can you try the following sandbox?

https://stackblitz.com/edit/react-ts-wmbqww?file=App.tsx

I've removed react-spring to focus on the lib only. The red square uses the genuine useDrag from the library while the green square uses a simplified implementation of useDrag.

This issue seems to still be present, the red square still has significant stuttering while the green square is smooth as expected

HeartofPhos commented 1 year ago

I've rerecorded the issue at 240fps and slowed the footage to 0.25 speed.

https://user-images.githubusercontent.com/43216176/236677925-faf3e19e-0110-4317-aa9b-fdea5c10b30d.mp4

dbismut commented 1 year ago

Thanks. There's a few things we could try but I'm afraid we'll have to try a debug session together as I'm not sure I'll be able to reproduce the issue on my own, not having a 120hz monitor. Can you try adding me on discord?

dbismut commented 1 year ago

For reference and following our call @HeartofPhos, we've observed that the issue comes from this line: https://github.com/pmndrs/use-gesture/blob/4dcbf8c601281f726d8176a20e27e314a3941e64/packages/core/src/engines/DragEngine.ts#L155

In fact, because of Firefox protection against fingerprinting, the event.timeStamp precision is reduced which, on high framerate monitors results in successive events to be skipped because of this equality check.

The options would be:

  1. don't calculate kinematics for events with a similar timestamp
  2. use performance.now() rather than event.timeStamp (but this may have a performance cost).