How do i make my stack navigation performant?

Viewed 300

I am using react-navigation v4 in my app on Android and i have both stack, bottom and top tabs navigation in the app. The app runs as around 40+ fps and drops to around 10 fps when im navigating through the bottom tabs and the top tabs. When i try to navigate to a different screen in the stack, it drops to -2.5fps and the takes a couple of seconds to open the new screen. Ive read a thing or two on the web, using

'''
import {enableScreen} from 'react-native-screens'
'''

I read this was to help but the performance is still bad. Any ideas on how to solve my problem?

Below is the preview of my code in the App.js file :

    import React from "react";
import {
  StyleSheet,
  Text,
  View,
  Button,
  Dimensions,
  StatusBar,
} from "react-native";
import { createAppContainer } from "react-navigation";
import { createStackNavigator } from "react-navigation-stack";
import { createMaterialBottomTabNavigator } from "react-navigation-material-bottom-tabs";
import { MaterialIcons, FontAwesome } from "react-native-vector-icons";

import HomeScreen from "./Screens/HomeScreen";
import Search from "./Screens/SearchScreen";
import Library from "./Screens/LibraryScreen";
import Colors from "./Components/Colors";
import { DEVICE_HEIGHT, DEVICE_WIDTH } from "./Components/Device_Dimension";
import KelenchaDetails from "./Screens/KelenchaDetails";

const HomeScreenStack = createStackNavigator({
  Home: {
    screen: HomeScreen,
    navigationOptions: {
      headerShown: false,
    },
    params: {
      colors: [
        Colors.albumCard1,
        Colors.albumCard2,
        Colors.albumCard3,
        Colors.albumCard4,
      ],
    },
  },
  Kelencha: {
    screen: KelenchaDetails,
    navigationOptions: {
      headerShown: false,
    },
  },
});

const KelenchsDetailsContainer = createAppContainer(HomeScreenStack);

const DefaultHomeScreeen = createMaterialBottomTabNavigator(
  {
    HomeScreen: {
      screen: KelenchsDetailsContainer,
      navigationOptions: {
        tabBarLabel: "Home",
      },
    },
    SearchScreen: {
      screen: Search,
      navigationOptions: {
        tabBarIcon: () => (
          <FontAwesome name="search" size={25} color={Colors.albumCard2} />
        ),
        tabBarLabel: "Search",
      },
    },
    LibraryScreen: {
      screen: Library,
      navigationOptions: {
        tabBarIcon: () => (
          <MaterialIcons
            name="library-music"
            size={25}
            color={Colors.albumCard2}
          />
        ),
        tabBarLabel: "Library",
      },
    },
  },
  {
    inactiveColor: Colors.secondaryBackground,
    activeColor: Colors.lightCardText,
    barStyle: {
      backgroundColor: Colors.primaryBackground,
      overflow: "hidden",
      height: DEVICE_HEIGHT * 0.1,
      borderTopRightRadius: DEVICE_WIDTH * 0.1,
      borderTopLeftRadius: DEVICE_WIDTH * 0.1,
    },
  }
);

const AppContent = createAppContainer(DefaultHomeScreeen);

export default function App() {
  return (
    <View style={styles.container}>
      <AppContent />
      <StatusBar barStyle="light-content" />
    </View>
  );
}

This is the code in my HomeScreen:

 import React from "react";
import { StyleSheet, View, Text, FlatList } from "react-native";

import { createMaterialTopTabNavigator } from "react-navigation-tabs";
import { createAppContainer } from "react-navigation";

import Colors from "../Components/Colors";
import AlbumCard from "../Components/HomeScreen/AlbumCard";
import { DEVICE_HEIGHT, DEVICE_WIDTH } from "../Components/Device_Dimension";
import { ALBUMS } from "../Components/HomeScreen/Albumns";
import DetailCard from "../Components/HomeScreen/DetailCard";

const CARD_WIDTH = DEVICE_WIDTH * 0.32;

const TrialComp = () => {
  return (
    <View style={{ flex: 1, alignItems: "center" }}>
      <DetailCard />
      <DetailCard />
      <DetailCard />
    </View>
  );
};

const DetialsNav = createMaterialTopTabNavigator(
  {
    Recent: {
      screen: TrialComp,
      navigationOptions: {},
    },
    Composers: {
      screen: TrialComp,
    },
    Choirs: {
      screen: TrialComp,
    },
  },
  {
    tabBarOptions: {
      labelStyle: {
        color: "#212423",
        fontSize: 14,
      },
      tabStyle: {
        width: DEVICE_WIDTH * 0.33,
      },
      indicatorStyle: {
        width: DEVICE_WIDTH * 0.023,
        height: DEVICE_HEIGHT * 0.013,
        borderRadius: DEVICE_WIDTH * 0.023 * 0.6,
        marginHorizontal: DEVICE_WIDTH * 0.33 * 0.42,
        backgroundColor: Colors.albumCard2,
      },
      style: {
        backgroundColor: Colors.secondaryBackground,
      },
    },
  }
);

const Detail = createAppContainer(DetialsNav);

const HomeScreen = (props) => {
  let {
    albumCardsContainer,
    albumSection,
    scrollableDetailSection,
    homeScreenContainer,
    homeScreenTextHeader,
    headerText,
  } = styles;
  return (
    <View style={homeScreenContainer}>
      <View style={albumSection}>
        <View style={homeScreenTextHeader}>
          <Text style={headerText}>Try Some</Text>
        </View>
        <View style={albumCardsContainer}>
          <FlatList
            data={ALBUMS}
            showsHorizontalScrollIndicator={false}
            keyExtractor={(item, index) => index.toString()}
            horizontal={true}
            renderItem={(album) => (
              <AlbumCard
                navigation={props.navigation}
                source={album.item.source}
                albumTitle={album.item.title}
                theme={album.item.theme}
                textColor={album.item.textColor}
              />
            )}
          />
        </View>
      </View>
      <View style={scrollableDetailSection}>
        <Detail />
      </View>
    </View>
  );
};
1 Answers

I experimented some similar but with drawer in v4. Use useScreens() in my index.js (App component) solve this drops of fps put it in the top of the file (not inner the component).

The version for v4 that I use in my legacy app is "react-native-screens": "^1.0.0-alpha.23"

import { useScreens } from 'react-native-screens';
useScreens();

Also in v5 I don't experimented any issue with navigation without react native screens(drop fps). So if that is an option you can migrate it.

Related