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 ofuseDrag
.
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:
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:
- don't calculate kinematics for events with a similar timestamp
- use
performance.now()
rather thanevent.timeStamp
(but this may have a performance cost).