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

  1. Create a screen with many views
  2. Push a simple screen
  3. 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)

Most upvoted comments

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.