React navigation v5 慢,因为在打开抽屉之前重新呈现当前屏幕
React navigation v5 slow because rerenders current screen before opening drawer
我正在开发一个更大的应用程序,打开抽屉时有些延迟。抽屉动画开始需要大约 1 秒。
我使用 react profiler 对其进行了调查,发现 抽屉已呈现,并且在抽屉打开之前重新呈现了当前屏幕 。这让事情感觉很慢,我不会怀疑当前屏幕会重新呈现。
这是我的 伪 导航堆栈自上而下的样子:
//Toplevel
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
const RootStack = createStackNavigator();
<NavigationContainer ref={navRef} theme={navTheme} linking={linking}>
<RootStack.Navigator>
{loggedIn ? (
<RootStack.Screen component={inBetweenComponent} /> // => calls drawer
) : (
// auth screen
)}
</RootStack.Navigator>
</NavigationContainer>
const DrawerNavigator = () => {
const Drawer = createDrawerNavigator();
const route = useRoute();
const activeRoute = getFocusedRouteNameFromRoute(route);
return (
<Drawer.Navigator
drawerContent={props => <DrawerContent {...props} activeRoute={activeRoute} />}
>
<Drawer.Screen name="Notifications" component={NotificationsNavigator} />
<Drawer.Screen name="Conversations" component={ConversationsNavigator} />
</Drawer.Navigator>
}
const DrawerContent = ({ activeRoute }) => {
const navigation = useNavigation();
return (
<DrawerContentScrollView>
<TouchableNative onPress={goToNotifications} >..some text...</TouchableNative>
<TouchableNative onPress={goToConversations} >..some text...</TouchableNative>
</DrawerContentScrollView>
)
}
const NotificationsNavigator = ({ navigation }) => {
const Stack = createStackNavigator();
return (
<Stack.Navigator
screenOptions={{
headerLeft: () => <HeaderLeft navigation={navigation} />, // -> contains open drawer button
}}
initialRouteName="Notifications"
>
<Stack.Screen
name="Notifications"
component={NotificationsScreen}
/>
</Stack.Navigator>
);
}
const HeaderLeft = () => {
const navigation = useNavigation();
const openNavigation = () => {
navigation.openDrawer();
};
<TouchableNative /*someicon*/ onPress={openNavigator} />
我想知道:
- 当前活动屏幕在抽屉打开之前重新渲染是否正常?
- 如果正常,有没有办法重新渲染当前活动屏幕?我尝试了一个使用 useMemo + areEqual 函数的解决方案,其中 isDrawerOpen (useIsDrawerOpen) 从父级发送。但这并不一致,经常给出错误或未定义的值。
- 非常感谢任何其他关于为什么这个堆栈可能很慢的指示。
提前致谢!
打开抽屉时屏幕重新呈现的原因是您在 DrawerNavigator
组件中定义了抽屉。
这意味着每次 React Navigation 想要找到抽屉时,不仅要重新加载当前屏幕,还要重新加载抽屉中的每个屏幕。
将 const Drawer = createDrawerNavigator();
移到 DrawerNavigator 之外应该可以解决您的问题。
我正在开发一个更大的应用程序,打开抽屉时有些延迟。抽屉动画开始需要大约 1 秒。
我使用 react profiler 对其进行了调查,发现 抽屉已呈现,并且在抽屉打开之前重新呈现了当前屏幕 。这让事情感觉很慢,我不会怀疑当前屏幕会重新呈现。
这是我的 伪 导航堆栈自上而下的样子:
//Toplevel
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
const RootStack = createStackNavigator();
<NavigationContainer ref={navRef} theme={navTheme} linking={linking}>
<RootStack.Navigator>
{loggedIn ? (
<RootStack.Screen component={inBetweenComponent} /> // => calls drawer
) : (
// auth screen
)}
</RootStack.Navigator>
</NavigationContainer>
const DrawerNavigator = () => {
const Drawer = createDrawerNavigator();
const route = useRoute();
const activeRoute = getFocusedRouteNameFromRoute(route);
return (
<Drawer.Navigator
drawerContent={props => <DrawerContent {...props} activeRoute={activeRoute} />}
>
<Drawer.Screen name="Notifications" component={NotificationsNavigator} />
<Drawer.Screen name="Conversations" component={ConversationsNavigator} />
</Drawer.Navigator>
}
const DrawerContent = ({ activeRoute }) => {
const navigation = useNavigation();
return (
<DrawerContentScrollView>
<TouchableNative onPress={goToNotifications} >..some text...</TouchableNative>
<TouchableNative onPress={goToConversations} >..some text...</TouchableNative>
</DrawerContentScrollView>
)
}
const NotificationsNavigator = ({ navigation }) => {
const Stack = createStackNavigator();
return (
<Stack.Navigator
screenOptions={{
headerLeft: () => <HeaderLeft navigation={navigation} />, // -> contains open drawer button
}}
initialRouteName="Notifications"
>
<Stack.Screen
name="Notifications"
component={NotificationsScreen}
/>
</Stack.Navigator>
);
}
const HeaderLeft = () => {
const navigation = useNavigation();
const openNavigation = () => {
navigation.openDrawer();
};
<TouchableNative /*someicon*/ onPress={openNavigator} />
我想知道:
- 当前活动屏幕在抽屉打开之前重新渲染是否正常?
- 如果正常,有没有办法重新渲染当前活动屏幕?我尝试了一个使用 useMemo + areEqual 函数的解决方案,其中 isDrawerOpen (useIsDrawerOpen) 从父级发送。但这并不一致,经常给出错误或未定义的值。
- 非常感谢任何其他关于为什么这个堆栈可能很慢的指示。
提前致谢!
打开抽屉时屏幕重新呈现的原因是您在 DrawerNavigator
组件中定义了抽屉。
这意味着每次 React Navigation 想要找到抽屉时,不仅要重新加载当前屏幕,还要重新加载抽屉中的每个屏幕。
将 const Drawer = createDrawerNavigator();
移到 DrawerNavigator 之外应该可以解决您的问题。