react-native-screens: Android + React-Navigation: Slow back animation/transitions
Description
I’ve recently been testing with enableScreens(true);
and it seems to work great for simple screens. However, for screens with many views (e.g., a very large list rendered in a flatlist), going back to it from another screen results in very slow animations. Basically, you can see the black background (or w/e bg your app has), it freezes half a second, and the animation continues.
This does not happen when screens is not used, I’m guessing because all the views are there already. The initial view is lazy loaded when pushed, so this is not an issue when opening the screen, but it is awfully sluggish when another screen is popped.
I could use detachPreviousScreen: true
on the pushed screen, but then that would make that screen very slow instead.
Is using the native stack navigator the only way to improve this? Why even with the native driver the animations are so bad?
Screenshots
Steps To Reproduce
- Create a screen with many views
- Push a simple screen
- Pop the screen, observe the animations
Note: I’m using the regular StackNavigator (createStackNavigator
), and not the native one, but I’m also using the native driver.
Expected behavior
Animations should not be blocked by screens being added to the tree.
Actual behavior
Slow animations
Snack or minimal code example
react-navigation config
const animationConfig = {
animation: 'spring',
config: {
stiffness: 1200,
damping: 100,
mass: 3,
overshootClamping: true,
restDisplacementThreshold: 0.01,
restSpeedThreshold: 0.01,
useNativeDriver: true,
},
};
let animationInterp = CardStyleInterpolators.forHorizontalIOS;
const Stack = createStackNavigator();
const StackNavigator = ({user}) => {
let screens;
screens = (
<React.Fragment>
<Stack.Screen
name="Home"
component={Home}
options={({navigation, route}) => {
return {
title: 'Home',
header: (props) => (
<HomeHeader navigation={navigation} route={route} />
),
};
}}
/>
... other screens ...
)
return (
<Stack.Navigator
headerMode="screen"
screenOptions={({navigation, route}) => {
return {
header: (props) => (
<MainHeader
back={true}
title={props.scene.descriptor.options.title}
navigation={navigation}
route={route}
/>
),
gestureEnabled: false,
transitionSpec: {
open: animationConfig,
close: animationConfig,
},
cardStyleInterpolator: animationInterp,
};
}}>
{screens}
</Stack.Navigator>
);
Package versions
- React:
- React Native:
- React Native Screens:
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 2
- Comments: 19 (7 by maintainers)
Tried on a pixel 6 with android 12 as well and no issues, must be this pixel 5 🥲
We haven’t investigated it further as it seemed like not in scope of
react-native-screens
library. I think it would be good to submit another issue with a reproduction and a link to this issue if the problem is still occuring.