My app lets the user see their location while they complete a task. After the user completes their task, they are navigated to the next map screen until that task is completed. This goes on until their task is finished to completion (after the 4th map screen.) To prevent a memory leak, I am using a mount/unmount component and have also implemented an ActivityIndicator to render while the map is loading, but it can take up to 10 seconds, which is less than ideal when they're in the middle of a task.
So far I have turned off trackViewChanges, am using an icon for my custom marker, and have tried running in development mode in expo, as all of these have claimed to decrease lag time, but none have worked. Below is the code used to isolate the user's position, coupled with the mounting and unmounting component. It is the same from one maps screen to another.
How should I go about cutting down lag time?
function Screen({navigation}) {
const [user_latitude, setUserLatitude] = useState(0)
const [user_longitude, setUserLongitude] = useState(0)
const [position_error, setPositionError] = useState(null)
const [ isLoading, setIsLoading ] = useState(true)
const [ location, setLocation ] = useState(null);
const renderLoading = () => {
if (isLoading) {
return (
<View style = {{flex:1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#d3d3d3', height: height*0.75, width: width}}>
<ActivityIndicator
color = 'black'
size = 'large'
animated = {false}
/>
<Text style = { styles.text }>{i18n.t('')}</Text>
</View>
);
}else {
return null;
}
}
useFocusEffect(
React.useCallback(()=> {
let isActive = true;
const fetchGeoPosition = () => {
navigator.geolocation.getCurrentPosition(
position => {
if (isActive){
setUserLatitude(position.coords.latitude);
setUserLongitude(position.coords.longitude);
setPositionError(null);
console.log('Location Accessed')
}
setIsLoading(false)
},
error => isActive && setPositionError(error.message),
{enableHighAccuracy: true, timeout: 0, maximumAge: 1000}
);
}
const permission_get = async () => {
if (Platform.OS === 'android' && !Constants.isDevice) {
setErrorMsg(
'Oops, this will not work on Snack in an Android emulator. Try it on your device!'
);
return;
}
let { status } = await Location.requestPermissionsAsync();
if (status !== 'granted') {
setErrorMsg('Permission to access location was denied');
console.log('Not permitted')
return;
}
let location = await Location.getCurrentPositionAsync({});
setLocation(location);
console.log('Permitted')
}
permission_get()
fetchGeoPosition()
return () =>{
isActive = false
console.log('Location Severed')
}
},
[],
),
)
if (!exercise.trim()){
return;
}
Alert.alert(
(i18n.t('')),
(i18n.t('')),
[
{
text: (i18n.t('')),
onPress: () => navigation.navigate('Screen2')
},
{
text: (i18n.t('')),
}]
)
}
return(
<View style = {styles.container}>
<View style = {styles.header}>
<MapView
provider={PROVIDER_GOOGLE}
style={styles.map}
region= {{
latitude: user_latitude,
longitude: user_longitude,
latitudeDelta: 0.0451,
longitudeDelta: 0.0451
}}>
<Marker
coordinate={
{latitude: user_latitude,
longitude: user_longitude,
error: position_error,
}}
>
</Marker>
</MapView>
<View style = { styles.blank }>
<View style = {{flex:1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#fff' }}>
{(renderLoading())}
</View>
</View>
</View>
</View>
)
}
export {Screen};
const {height}= Dimensions.get("screen");
const { width } = Dimensions.get("screen")
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
backgroundColor: '#fff',
},
});