Closed Willham12 closed 2 weeks ago
Same result with better performance without using a state: https://snack.expo.dev/76p09SjKxZHh977msQHbj And here ist a version with native slider package: https://snack.expo.dev/ViKIaC3sai2I8cVaN_IU2
try to slider very fast from left to right over and over again and you feel the difference.
Hi @Willham12! Using state
will significantly decrease performance, that's why you should use SharedValue
. Here you can find example that also implements Slider
:
As you can see there are no performance issues:
https://github.com/user-attachments/assets/353d9722-ab6b-4950-b36b-d4cd2f4489cf
@m-bert but what if the progress depends on a state and this state can't replaced by a sharedValue?
If your state contains progress values (like on a scale from 0
to 100
), then you should definitely use SharedValue
. If not, you can try useDerivedValue and pass state
into return value, e.g.:
import {useDerivedValue} from 'react-native-reanimated';
function App() {
const [isOpen, setOpen] = React.useState(false);
const sv = useDerivedValue(() => {
return isOpen;
})
// ...
}
Here you can find another example of slider
.
Nah, none of these solutions working for me. I have a very complex ui based on a circular slider and if release the slider onUpdate() still getting fired until the positions are processed. Same if the Component with the Gesture.Pan() are not updating by a state change. Based on the circular slider position i have to calculate a price based on a very complex price model and i don't now why but the new gesture api blocks the whole js thread. No issue with the old API.
We've already showed that it is possible to create smooth slider. I've also provided 2 examples of how to do it. If your app has such level of complexity, then there's not much that we can do. Especially if you will use React states
.
Here is a perfect example, check the log. https://snack.expo.dev/oQjqMz_sLClc9wXmmI9WW With old API the while loop takes almost 0ms.
I'm not exactly sure what you mean by checking the log, could you provide an example with the old API where it works as you'd expect to compare to?
Also, I've noticed that you're using .runOnJS
modifier on a gesture. This prevents it from being executed on the UI thread and adds a delay between receiving the event and applying the updated values to the views so that they are displayed on the screen. If you want to use a gesture to drive an animation you should do it on the UI thread and use runOnJS
function from Reanimated to schedule things that cannot be executed on the UI thread (like state updates).
Coming back to your original snack, you shouldn't use state to drive animations. If you need other components to update in response to a gesture change, consider moving them to use useAnimatedProps
or scheduling a state update in response to a shared value change in useAnimatedReaction
.
If i removed a huge part of the underlying components tree then the new gesture api works as expected. Not sure why the legacy gesture api works better.
After more investigation i notice that the JS frame rate drops down to 0 with new gesture api and with the legacy version its always above 20.
@j-piasecki here a video with the legacy PanGestureHandler:
https://github.com/user-attachments/assets/8f59163a-2db7-4459-8c3e-98eebf3c77bf
and here with the new Gesture.Pan() API:
https://github.com/user-attachments/assets/cdce411d-e4bb-448e-8dc9-14a5d63fd5dd
I can't share the real ui but the underlying computation is not simple but with the new gesture api the performance breaks down. panGesture is wrapped into a useMemo and for the progress i'm using useDerivedValue. Also with new gesture api i receive onUpdate events while the knob reached already the final position.
const panGesture = useMemo(() => {
return Gesture.Pan()
.enabled(!isDisabled)
.minDistance(1)
.minPointers(1)
.onBegin((event) => {
...
I understand that you cannot post the entire code, but could you share some more details that may be important here?
Description
Bad performance with new gesture pan API. I have a similar circular slider with the same issue and with the old api no issues:
Steps to reproduce
Open the Snack and slider fast from left to right
Snack or a link to a repository
https://snack.expo.dev/qFQCJMaMaZBreK0vOgQ0w
Gesture Handler version
2.20.2
React Native version
0.74.2
Platforms
iOS
JavaScript runtime
Hermes
Workflow
React Native (without Expo)
Architecture
Paper (Old Architecture)
Build type
Release mode
Device
iOS simulator
Device model
Iphone 15
Acknowledgements
Yes