diff --git a/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator.js b/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator.js
deleted file mode 100644
index 20baf44b23f4..000000000000
--- a/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator.js
+++ /dev/null
@@ -1,36 +0,0 @@
-import {createStackNavigator} from '@react-navigation/stack';
-import React from 'react';
-import ReportScreenWrapper from '@libs/Navigation/AppNavigator/ReportScreenWrapper';
-import getCurrentUrl from '@libs/Navigation/currentUrl';
-import FreezeWrapper from '@libs/Navigation/FreezeWrapper';
-import styles from '@styles/styles';
-import SCREENS from '@src/SCREENS';
-
-const Stack = createStackNavigator();
-
-const url = getCurrentUrl();
-const openOnAdminRoom = url ? new URL(url).searchParams.get('openOnAdminRoom') : undefined;
-
-function CentralPaneNavigator() {
- return (
-
-
-
-
-
- );
-}
-
-export default CentralPaneNavigator;
diff --git a/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/BaseCentralPaneNavigator.js b/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/BaseCentralPaneNavigator.js
new file mode 100644
index 000000000000..a1646011e560
--- /dev/null
+++ b/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/BaseCentralPaneNavigator.js
@@ -0,0 +1,33 @@
+import {createStackNavigator} from '@react-navigation/stack';
+import React from 'react';
+import ReportScreenWrapper from '@libs/Navigation/AppNavigator/ReportScreenWrapper';
+import getCurrentUrl from '@libs/Navigation/currentUrl';
+import styles from '@styles/styles';
+import SCREENS from '@src/SCREENS';
+
+const Stack = createStackNavigator();
+
+const url = getCurrentUrl();
+const openOnAdminRoom = url ? new URL(url).searchParams.get('openOnAdminRoom') : undefined;
+
+function BaseCentralPaneNavigator() {
+ return (
+
+
+
+ );
+}
+
+export default BaseCentralPaneNavigator;
diff --git a/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/index.js b/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/index.js
new file mode 100644
index 000000000000..711dd468c77d
--- /dev/null
+++ b/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/index.js
@@ -0,0 +1,10 @@
+import React from 'react';
+import BaseCentralPaneNavigator from './BaseCentralPaneNavigator';
+
+// We don't need to use freeze wraper on web because we don't render all report routes anyway.
+// You can see this optimalization in the customStackNavigator.
+function CentralPaneNavigator() {
+ return ;
+}
+
+export default CentralPaneNavigator;
diff --git a/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/index.native.js b/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/index.native.js
new file mode 100644
index 000000000000..45ab2f070717
--- /dev/null
+++ b/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/index.native.js
@@ -0,0 +1,13 @@
+import React from 'react';
+import FreezeWrapper from '@libs/Navigation/FreezeWrapper';
+import BaseCentralPaneNavigator from './BaseCentralPaneNavigator';
+
+function CentralPaneNavigator() {
+ return (
+
+
+
+ );
+}
+
+export default CentralPaneNavigator;
diff --git a/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.js b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.js
index ae36f4aff9ad..194b86259107 100644
--- a/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.js
+++ b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.js
@@ -1,8 +1,9 @@
import {createNavigatorFactory, useNavigationBuilder} from '@react-navigation/native';
import {StackView} from '@react-navigation/stack';
import PropTypes from 'prop-types';
-import React, {useRef} from 'react';
+import React, {useMemo, useRef} from 'react';
import useWindowDimensions from '@hooks/useWindowDimensions';
+import NAVIGATORS from '@src/NAVIGATORS';
import CustomRouter from './CustomRouter';
const propTypes = {
@@ -25,6 +26,24 @@ const defaultProps = {
screenOptions: undefined,
};
+function splitRoutes(routes) {
+ const reportRoutes = [];
+ const rhpRoutes = [];
+ const otherRoutes = [];
+
+ routes.forEach((route) => {
+ if (route.name === NAVIGATORS.CENTRAL_PANE_NAVIGATOR) {
+ reportRoutes.push(route);
+ } else if (route.name === NAVIGATORS.RIGHT_MODAL_NAVIGATOR) {
+ rhpRoutes.push(route);
+ } else {
+ otherRoutes.push(route);
+ }
+ });
+
+ return {reportRoutes, rhpRoutes, otherRoutes};
+}
+
function ResponsiveStackNavigator(props) {
const {isSmallScreenWidth} = useWindowDimensions();
@@ -40,12 +59,25 @@ function ResponsiveStackNavigator(props) {
getIsSmallScreenWidth: () => isSmallScreenWidthRef.current,
});
+ const stateToRender = useMemo(() => {
+ const {reportRoutes, rhpRoutes, otherRoutes} = splitRoutes(state.routes);
+
+ // Remove all report routes except the last 3. This will improve performance.
+ const limitedReportRoutes = reportRoutes.slice(-3);
+
+ return {
+ ...state,
+ index: otherRoutes.length + limitedReportRoutes.length + rhpRoutes.length - 1,
+ routes: [...otherRoutes, ...limitedReportRoutes, ...rhpRoutes],
+ };
+ }, [state]);
+
return (
diff --git a/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.native.js b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.native.js
new file mode 100644
index 000000000000..ae36f4aff9ad
--- /dev/null
+++ b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.native.js
@@ -0,0 +1,60 @@
+import {createNavigatorFactory, useNavigationBuilder} from '@react-navigation/native';
+import {StackView} from '@react-navigation/stack';
+import PropTypes from 'prop-types';
+import React, {useRef} from 'react';
+import useWindowDimensions from '@hooks/useWindowDimensions';
+import CustomRouter from './CustomRouter';
+
+const propTypes = {
+ /* Determines if the navigator should render the StackView (narrow) or ThreePaneView (wide) */
+ isSmallScreenWidth: PropTypes.bool.isRequired,
+
+ /* Children for the useNavigationBuilder hook */
+ children: PropTypes.oneOfType([PropTypes.func, PropTypes.node]).isRequired,
+
+ /* initialRouteName for this navigator */
+ initialRouteName: PropTypes.oneOf([PropTypes.string, PropTypes.undefined]),
+
+ /* Screen options defined for this navigator */
+ // eslint-disable-next-line react/forbid-prop-types
+ screenOptions: PropTypes.object,
+};
+
+const defaultProps = {
+ initialRouteName: undefined,
+ screenOptions: undefined,
+};
+
+function ResponsiveStackNavigator(props) {
+ const {isSmallScreenWidth} = useWindowDimensions();
+
+ const isSmallScreenWidthRef = useRef(isSmallScreenWidth);
+
+ isSmallScreenWidthRef.current = isSmallScreenWidth;
+
+ const {navigation, state, descriptors, NavigationContent} = useNavigationBuilder(CustomRouter, {
+ children: props.children,
+ screenOptions: props.screenOptions,
+ initialRouteName: props.initialRouteName,
+ // Options for useNavigationBuilder won't update on prop change, so we need to pass a getter for the router to have the current state of isSmallScreenWidth.
+ getIsSmallScreenWidth: () => isSmallScreenWidthRef.current,
+ });
+
+ return (
+
+
+
+ );
+}
+
+ResponsiveStackNavigator.defaultProps = defaultProps;
+ResponsiveStackNavigator.propTypes = propTypes;
+ResponsiveStackNavigator.displayName = 'ResponsiveStackNavigator';
+
+export default createNavigatorFactory(ResponsiveStackNavigator);