-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RN 0.61: Animated.color causes "excessive number of pending callbacks" #381
Comments
I get the same error in some conditions using react-navigation 5.0.0 (unstable) |
I have the same on: [email protected], react-navigation@4 and latest reanimated. I am not sure how to debug this, but will keep looking. |
i wonder if it's something to do with the TurboModules API changes |
This commit looks relevant: facebook/react-native@1e45a41. This warning was added in 0.61.0. Do you experience this issue on devices running in release mode? Or only development mode in the simulator? I currently only see it in development mode on the simulator. My guess is: for most libraries, this warning message is a good way to find certain types of bugs. However, for this library, a lot of callbacks is sometimes expected behavior (e.g. stuff happening after a pan gesture recognizer updates coordinates)...and everything is just slower in development mode. |
You're right! I couldn't replicate this on release mode. It seems to happen only on debug mode. That's sad, I had to remove a lot of animations temporarily 'cause of it... any idea how we could solve it? Can we fix on our side or only contacting Thanks! |
The discussion for 0.61.0 is happening here: |
Cc @sahrens |
Is anyone able to create a simple repro we can drop into a fresh project, without using any third party libraries? I think that would be necessary for us to be able to effectively debug and fix this. edit I didn’t realize this was the reanimated repo. Heh, whoops. Needing to make a stand-alone repro without 3rd party deps doesn’t make much sense then. ;-) |
@TheSavior how can I help on this? |
@felippepuhle, we need an answer to the why this is happening. I imagine the smallest repro you can (with reanimated) would be a step in the right direction. |
@TheSavior the best example I could get for now was this: https://github.com/felippepuhle/rn-reanimated-bug Nothing happens immediately. But changing duration here with fast refresh enabled will crash the app. In my app it happens only on some screens, but it's not related to the fast refresh itself. Maybe something related to mounting/unmounting components (my app crashes just after changing the condition to mount/unmount some components). I don't know if I was clear, if you need anything else just let me know. Thanks! |
Thanks for working on the repo case for the issue @felippepuhle Unfortunately I couldn't get the crash you mentioned when trying it. Can you share some more details about your environment? E.g. are you running on iOS/Android simulator or device? Xcode version etc |
I also tried changing duration mutliple times and saving file in order for fast refresh to pick it up (at least 50 times) and still didn't get that issue. After all of that I've set a breakpoint in |
But now after some time on it I suspect that I know where your issue is coming from. There is only one place in reanimated where we use RN's callbacks and it is when the animated node detaches. If you have more than 500 nodes that unmount at the same time we'd enqueue an equal number of calls with callbacks (we use callback on detach to remember the last value of animated node in JS so that if it is being reused we initiate it in native with that value). The relevant code in reanimated is here https://github.com/kmagiera/react-native-reanimated/blob/c841c34d1037e6b00a9f425e17782ccfbdb92a12/src/core/InternalAnimatedValue.js#L25 – I'll try to think how we can workaround this limitation (maybe we could use events, or maybe detect which nodes are not going to be reused such that we only use callbacks on the ones that will) |
Not sure if this helps, but here's code that runs into this issue, particularly when export const DeleteFooter = ({ onDelete, panY, panX }) => {
const distance = React.useRef(new Animated.Value(0));
const opacity = React.useRef(
Animated.interpolate(
distance.current,
{
inputRange: DELETE_RANGE,
outputRange: [1, 1, 0.95, 0.5]
}
)
);
const scaleTransform = React.useRef(
Animated.interpolate(
distance.current,
{
inputRange: DELETE_RANGE,
outputRange: [1.01, 1.0, 0.97, 0.95]
}
)
);
const backgroundColor = React.useRef(
interpolateColor(
distance.current,
{
inputRange: DELETE_RANGE,
outputRange: [
{
r: 120,
g: 120,
b: 120
},
{
r: 75,
g: 75,
b: 75
},
{
r: 50,
g: 50,
b: 50
},
{
r: 0,
g: 0,
b: 0
}
]
},
"rgb"
)
);
return (
<View pointerEvents="none" style={[styles.footer, styles.footerCenter]}>
<Animated.Code
exec={Animated.block([
Animated.set(
distance.current,
Animated.sqrt(
Animated.add(
Animated.multiply(
Animated.sub(MID_X_DELETE_BUTTON, panX),
Animated.sub(MID_X_DELETE_BUTTON, panX)
),
Animated.multiply(
Animated.sub(MID_Y_DELETE_BUTTON, panY),
Animated.sub(MID_Y_DELETE_BUTTON, panY)
)
)
)
)
])}
/>
<View
pointerEvents="none"
style={[
styles.footerSide,
{ alignItems: "center", justifyContent: "center" }
]}
>
<IconButton
onPress={onDelete}
Icon={IconTrash}
color="#fff"
size={DELETE_SIZE}
backgroundColor={backgroundColor.current}
opacity={opacity.current}
transform={[{ scale: scaleTransform.current }]}
borderColor="#fff"
type="fill"
/>
</View>
</View>
);
}; This callback is triggered when x and y update as well (via handlePan = ({
blockId,
isPanning,
x,
y
}: {
blockId: string;
isPanning: boolean;
x: number;
y: number;
}) => {
if (isPanning) {
const focusType = FocusType.panning;
if (blockId !== this.state.focusedBlockId) {
this.focusedBlockValue.setValue(blockId.hashCode());
}
if (this.state.focusType !== focusType) {
this.focusTypeValue.setValue(focusType);
}
this.setState({
focusedBlockId: blockId,
focusType
});
} else {
const { focusedBlockId, focusType } = this.state;
if (
focusedBlockId === blockId &&
focusType === FocusType.panning &&
isDeletePressed(x, y)
) {
this.deleteNode(blockId);
sendLightFeedback();
} else {
this.setState({
focusedBlockId: null,
focusType: null
});
this.focusedBlockValue.setValue(-1);
this.focusTypeValue.setValue(-1);
}
}
}; |
Yes, I think I know what the issue is now. Note that the callbacks number check only runs in DEV which explains why you are not seeing this on release builds: facebook/react-native@1e45a41 |
Sure, I'm running IOS simulator with Xcode 10.2.1, but it already happened on my device too. I didn't try on Android yet (our app is 100% IOS for now). Hope that helps. Thank you! |
@felippepuhle I dug into |
We just landed a PR to core that changes this warning to only fire once the first time it occurs. That might also make this issue less high severity. |
The PR in question: https://github.com/facebook/react-native/pull/26508/files Thanks for the heads up @TheSavior |
That PR has shipped in RN 0.61.2 and has fixed the issue for me 👍 |
Summary: This warning happens when `react-native-reanimated` nodes are unmounted. I don't think the amount of Reanimated nodes we're using is excessive, since performance is okay on old Android phones. Some more context [here](software-mansion/react-native-reanimated#381). Apparently this warning should stop occurring in Reanimated 2. Reviewers: palys-swm Reviewed By: palys-swm Subscribers: KatPo, zrebcu411, Adrian Differential Revision: https://phabricator.ashoat.com/D185
Hey guys, how are you?
Just updated react native version to 0.61 (rc) and now my app is crashing on some screens that use color interpolation.
We have a theme based template, so I created a function that parses hex colors using polished:
Any tips on this?
Thanks!
The text was updated successfully, but these errors were encountered: