pmndrs / use-gesture

👇Bread n butter utility for component-tied mouse/touch gestures in React and Vanilla Javascript.

Home Page:https://use-gesture.netlify.app

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

useDrag is noticeably less responsive than useMove using Firefox

HeartofPhos opened this issue · comments

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:

  • Use Gesture version: 10.2.24
  • Device: PC
  • OS: Windows 10
  • Browser: Firefox 109.0.1 (64-bit)

Checklist:

  • I've read the documentation.
  • If this is an issue with drag, I've tried setting touch-action: none to the draggable element.

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.

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

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.

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

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

stutter.mp4

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?

For reference and following our call @HeartofPhos, we've observed that the issue comes from this line:

if (state.type === event.type && event.timeStamp === state.timeStamp) return

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).