Attaching (for example creating Animated.Value or using cond, eq, set, etc) and detaching nodes blocks JS thread
See original GitHub issueUpdated issue:
Reanimated uses a bridge to interact with the native side. Hight usage of bridge (lots of calls with lots of data to be passed) blocks the thread. Reanimated doing lots of calls. Even simple animation may produce 500-1500 calls. This is huge amount of calls. The main problem that it totally blocks the UI, the app might be showing just a blank screen or freeze until all the nodes are created and connected to each other.
You can verify it by using this simple snippet in your App.js
(works only with React Native CLI project):
import MessageQueue from 'react-native/Libraries/BatchedBridge/MessageQueue.js';
let count = 0;
const spyFunction = msg => {
if (msg.module === 'ReanimatedModule') {
console.log(++count, msg);
}
};
MessageQueue.spy(spyFunction);
Most of the calls are connectNodes
.
There is a thing which may reduce some amount of the calls – proc node. But it does not fix it for low-end devices;
You can verify the delay of rendering everything using this example: https://snack.expo.io/@terrysahaidak/reanimated-header
Original issue
I’m building a library which helps define an animation without any knowledge of reanimated. It’s inspired a lot by Animatable and called react-native-reanimatable.
It relies on Animated.Code
a lot since mostly I’m triggering animation by some props (changing value which runs/stops clocks).
But I’m noticed if I’m using several Animated.Code
, it creates animated nodes and blocks JS Thread. It’s noticeable on both Android and iOS.
You can check it out here (on my Xiaomi Mi5 and iPhone 7) with the Expo SDK 32: https://drive.google.com/open?id=1RUaVYcP6-VG332rGS7lA5RsyRXJh7VTP https://drive.google.com/open?id=15LDQphmnYyZtajFCERuugPgpUmeOIdG3
You can reproduce it using my lib example app: https://github.com/terrysahaidak/react-native-reanimatable/tree/master/Example
Navigate to Base transition. It renders 10 components with Animated.Code
under the hood. You can change count here:
https://github.com/terrysahaidak/react-native-reanimatable/blob/master/Example/screens/TransitionBase/TransitionBase.js#L103
Also here is some underlying logic:
Creating animation: https://github.com/terrysahaidak/react-native-reanimatable/blob/master/lib/core/createTransitionAnimation.js
Using of Animated.Code
: https://github.com/terrysahaidak/react-native-reanimatable/blob/master/lib/components/TransitionAnimation.js
Thank you for such a great library!
UPDATE:
I’ve figured out that Animation.Code
itself doesn’t block the thread, but creating animation values and nodes do.
Issue Analytics
- State:
- Created 5 years ago
- Reactions:9
- Comments:13 (8 by maintainers)
Top GitHub Comments
Hi @michalsek, did you check out my original comment here? The problem not with my library I’ve used as an example here.
The problem is that reanimated does too many calls to the bridge. You can easily count them using this snippet with any example:
For simply animation it generates thousands of calls where React Native Animated produces 100-200. This is a huge difference. You may not notice it on iOS, but on android, even on fast phone like my pixel 3 it is noticable.
We’ve tried already to fix it using JSI, but it didn’t really help. @chrfalch made a fork for iOS where it was 2-3 faster. But there is almost no problem with it on iOS. My fork with JSI on android was 30% faster. This is just nothing.
Also to fix it @chrfalch created proc node. It does reduce amount of nodes created. But still, unfortunately, on low-end android it’s unusable for most of the cases.
@kmagiera as well as @osdnk are aware of this problem.
For the ones interested:
https://twitter.com/kzzzf/status/1263157145572442112
Also, I’ve had similar problems on complex animation graphs. I wasn’t really able to optimize much the mount phase, but if you memoize the graph aggressively (ie, avoid creating new node instances), I’ve found updates/re-renders are less expensive. Didn’t measure the bridge calls but I guess it helps.