在过去的5个月中,我们一直在开发的应用程序中使用反应导航。
从昨天开始,反应导航器开始以4-8秒的延迟导航到屏幕。我删除了在screenProps中传递的所有变量,但仍然存在相同的问题。
我正在通过检查在执行navigation()函数之前以及componentWillMount()之间的时间来测试延迟,并且我在这之间获得了4-8秒的时间。 有经验的人都知道为什么navigation()会花这么长时间吗?
它只是开始以这种方式对导航器进行了一些更改:|
我正在真实的android设备上进行调试模式测试,但是我已经发布了测试版本,并且延迟仍然存在。
我的导航器:
import React, { Component } from 'react';
import { createStackNavigator, HeaderBackButton, createAppContainer } from 'react-navigation';
import { colors } from 'assets/styles/colors.js';
import RegistrationInputScreen from 'components/Registration/Input.js';
import RegistrationVerificationScreen from 'components/Registration/Verification.js';
import MainScreen from 'screens/MainScreen';
import Conversation from 'components/Messages/Conversation';
import Private from 'components/FirstTime/Private.js';
import Description from 'components/FirstTime/Description.js';
import CategoriesScreen from 'components/FirstTime/CategoriesScreen.js';
import Professional from 'components/FirstTime/Professional.js';
import Home from 'components/Home.js';
import SecretScreen from 'screens/SecretScreen.js';
import Map from 'components/Map/Map.js';
import ProfileScreen from 'components/Profile/Profile.js';
import EditProfile from 'components/Profile/EditProfile.js';
import PublicProfile from 'components/Profile/PublicProfile.js';
import Settings from 'components/Profile/Settings';
import {setTopLevelNavigator, navigate} from './NavigationService';
export default class RootNavigator extends Component {
constructor(props){
super(props)
}
render() {
console.log("PROPERTIES IN ROOT NAVIGATOR", this.props);
return (
<Navigator />
);
}
}
// ref={navigatorRef => {
// setTopLevelNavigator(navigatorRef);
// }}
export const RootNav = createStackNavigator(
{
RegistrationOptions: {
screen: Home,
navigationOptions: {
header: null
},
},
RegistrationInput: {
screen: RegistrationInputScreen,
navigationOptions: ({navigation}) => (setHeader(null, navigation))
},
RegistrationVerification: {
screen: RegistrationVerificationScreen,
navigationOptions: ({navigation}) => (setHeader('Registration Verification1', navigation))
},
Map: {
screen: Map,
navigationOptions: {
header: null
}
},
MainScreen: MainScreen,
Private: {
screen: Private,
navigationOptions: ({navigation}) => (setHeader('Introduce yourself', navigation))
},
Interests: {
screen: CategoriesScreen,
navigationOptions: ({navigation}) => (setHeader('Back', navigation))
},
Description: {
screen: Description,
navigationOptions: ({navigation}) => (setHeader('Describe yourself', navigation))
},
Professional: {
screen: Professional,
navigationOptions: ({navigation}) => (setHeader('Professional', navigation))
},
Conversation: {
screen: Conversation,
navigationOptions: ({navigation}) => (setHeader(null, navigation))
},
Secret: {
screen: SecretScreen,
navigationOptions: ({navigation}) => (setHeader('Configure app', navigation))
},
Profile: {
screen: ProfileScreen,
navigationOptions: ({navigation}) => (setHeader('Profile', navigation))
},
Public: {
screen: PublicProfile,
navigationOptions: ({navigation}) => (setHeader('Profile', navigation))
},
EditProfile: {
screen: EditProfile,
navigationOptions: ({navigation}) => (setHeader('Edit profile', navigation))
},
Settings: {
screen: Settings,
navigationOptions: ({navigation}) => (setHeader('Settings', navigation))
},
}
);
export const Navigator = createAppContainer(RootNav);
const setHeader = (title=null, navigation) => {
let options = {
title: title,
headerStyle: {
backgroundColor: colors.bgRed,
shadowOpacity: 0,
shadowOffset: {
height: 0,
},
shadowRadius: 0,
elevation: 0
},
headerTitleStyle: { color:colors.white },
headerTransitionPreset: {headerMode: 'screen'},
cardShadowEnabled: false,
headerLeft: (
<HeaderBackButton
tintColor={colors.white} onPress={() => navigation.dispatch({ type: 'Navigation/BACK' }) }
/>
)
}
if(title === null) delete options.title;
return options;
}
答案 0 :(得分:0)
当我遇到导航问题时,这是由于屏幕渲染非常沉重造成的。
屏幕上可能有一些东西会导致这种性能吗?尝试仅在屏幕渲染中return null;
,看看问题是否仍然存在。
您使用哪个版本的反应导航?
答案 1 :(得分:0)
由于加载大量数据而发生此问题 背景或在应用中渲染时
例如:如果您具有项目列表以及进入应用程序的时间 并且列表数据非常大,整个数据将无法 一次渲染,向下滚动列表会花费一些时间。所以 在这种情况下,您可以添加分页(例如加载更多数据),或者 过滤器。 尝试检查在哪个屏幕上加载了大量数据
答案 2 :(得分:0)
由于没有适当的代码可以看到问题所在。但是用反应导航动画线程是主要问题。根据我的经验,您可以使用InteractionManager
。
只需使用以下代码等待渲染。
state = { is_initiated: false };
componentDidMount() {
InteractionManager.runAfterInteractions(() => {
this.setState({'is_initiated': true });
});
}
render() {
if(this.state.is_initiated) {
return (<Component />);
} else {
return (<Loader />);
}
}
答案 3 :(得分:0)
问题再次开始出现,我的动画也非常慢。我发现禁用远程调试是导航器缓慢导航和动画速度降低的原因。如果有人遇到这种情况,请尝试禁用远程调试。
答案 4 :(得分:0)
我的解决方法是在组件中监听focus
,还可以监听transitionEnd
事件,在尚未准备好时,我会渲染一个占位符。屏幕过渡会很流畅。
// useIsReady.ts
import { useNavigation } from '@react-navigation/native'
import React from 'react'
const useIsReady = (stack: boolean = true) => {
const navigation = useNavigation()
const [isReady, setIsReady] = React.useState(false)
React.useEffect(() => {
const unsubscribeFocus = navigation.addListener('focus', () => {
if (!isReady) setIsReady(true)
})
const unsubscribeTransitionEnd = stack
? // @ts-ignore
navigation.addListener('transitionEnd', () => {
if (!isReady) setIsReady(true)
})
: undefined
return () => {
unsubscribeFocus()
unsubscribeTransitionEnd && unsubscribeTransitionEnd()
}
}, [])
return isReady
}
export default useIsReady
某些组件...
const HeavyComponentThatMakeNavigationLooksCrap = () => {
const isReady = useIsReady()
return isReady ? ... : <Placeholder />
}
如果屏幕上有多个沉重的组件,最好直接在屏幕上使用它:
const ScreenWithMultipleHeavyComponents = () => {
const isReady = useIsReady()
return isReady ? ... : <ScreenPlaceholder />
// or
return (
<>
...
{isReady ? ... : <ComponentsPlaceholder />}
</>
)
}
这不是一个解决方案,因为如果您的组件确实很重,它仍然会阻塞js线程,这对于上面的react-navigation-heavy-screen
解决方案也是如此(请参见下面的PS )。尽管页面过渡将很平滑,但还是与上述解决方案相同。
PS:我最初将其发布为in this issue on React Navigation