shopify-react-native-performance-navigation-drawer
shopify-react-native-performance-navigation-drawer is an extension library atop @shopify/react-native-performance-navigation with additional helper methods for @react-navigation/drawer library.
Installation
- Add the JavaScript library dependency in the package.jsonfile:"dependencies": { ... "@shopify/react-native-performance": "npm:@amazon-devices/shopify__react-native-performance@~2.0.0", "@shopify/react-native-performance-navigation": "npm:@amazon-devices/shopify__react-native-performance-navigation@~3.0.0", "@shopify/react-native-performance-navigation-drawer": "npm:@amazon-devices/shopify__react-native-performance-navigation-drawer@~3.0.0", "@amazon-devices/react-native-reanimated": "~2.0.0", "@amazon-devices/react-native-gesture-handler": "~2.0.0" },
- Run the following command, which sets npm to use the pre-version 7 behavior for handling peer dependencies specifically for the current projecsts. This allows for more lenient package installation when dealing with potentially incompatible or outdated dependencies.
    npm config set legacy-peer-deps=true --location=project
- Add the Babel module resolver plugin to the devDependenciessection in thepackage.jsonfile:"devDependencies": { ... "babel-plugin-module-resolver": "~5.0.2", },
- Configure an alias for @amazon-devices/shopify__react-native-performance*in thepluginsection of thebabel.config.jsfile.plugins: [ ["module-resolver", { "alias": { "~@amazon-devices/shopify__react-native-performance(.*)": "@shopify/react-native-performance/\\1" } }], "@amazon-devices/react-native-reanimated/plugin" ]
- For projects using @amazon-devices/react-navigation_<X>@2.0.0libraries (where<X>represents specific components likestackornative), include these libraries in both thedependenciesandoverridessections of your package.json file. It is strongly recommended to upgrade to@amazon-devices/react-navigation_<X>@7.0.0, which introduces@amazon-devices/react-native-reanimatedsupport for enhanced performance and animations."dependencies": { ... "@amazon-devices/react-navigation__<X>": "~2.0.0", ... }, ... "overrides": { ... "@amazon-devices/react-navigation__<X>": "~2.0.0", ... },
- 
    Reinstall dependencies using npm installcommand.
- Restart metro with reset cache option npm start -- --reset-cache.
Examples
Profiling how long it takes to render the screens hosted inside the different tabs using the Drawer Navigator created via createProfiledDrawerNavigator function.
import React, { useCallback, useContext, useState } from 'react';
import { createProfiledDrawerNavigator } from '@shopify/react-native-performance-navigation-drawer';
import {
  LogLevel,
  PerformanceProfiler,
  RenderPassReport,
} from '@shopify/react-native-performance';
import { NavigationContainer } from '@amazon-devices/react-navigation__native';
import { StyleSheet, Text, View } from 'react-native';
import { ReactNavigationPerformanceView } from '@shopify/react-native-performance-navigation';
import { GestureHandlerRootView } from '@amazon-devices/react-native-gesture-handler';
type ReportContextState = {
  saveReport: (report: RenderPassReport) => void;
  findReport: (destinationScreen: string, sourceScreen?: string) => void;
};
const INITIAL_STATE = {
  saveReport: () => {},
  findReport: () => {},
};
const ReportContext = React.createContext<ReportContextState>(INITIAL_STATE);
const useReportContext = () => {
  return useContext(ReportContext);
};
const DrawerScreenA = () => {
  const { findReport } = useReportContext();
  const report = findReport('drawerScreenA', 'Drawer');
  return (
    <ReactNavigationPerformanceView
      screenName="drawerScreenA"
      interactive={true}
    >
      <View style={styles.container}>
        <Text style={styles.label}>Measuring navigation render time</Text>
        <Text style={styles.label}>
          New report is generated after each navigation from "Drawer" to "Drawer
          Screen A"
        </Text>
        <Text style={styles.text}>{JSON.stringify(report)}</Text>
      </View>
    </ReactNavigationPerformanceView>
  );
};
const DrawerScreenB = () => {
  const { findReport } = useReportContext();
  const report = findReport('drawerScreenB', 'Drawer');
  return (
    <ReactNavigationPerformanceView
      screenName="drawerScreenB"
      interactive={true}
    >
      <View style={[styles.container]}>
        <Text style={styles.label}>Measuring navigation render time</Text>
        <Text style={styles.label}>
          New report is generated after each navigation from "Drawer" to "Drawer
          Screen B"
        </Text>
        <Text style={styles.text}>{JSON.stringify(report)}</Text>
      </View>
    </ReactNavigationPerformanceView>
  );
};
const Drawer = createProfiledDrawerNavigator();
export const App = () => {
  const onReportPrepared = (report: RenderPassReport) => {
    saveReport(report);
  };
  const [reports, setReports] = useState<RenderPassReport[]>([]);
  const saveReport = useCallback((report: RenderPassReport) => {
    setReports((prev) => {
      const filtered = prev.filter(
        (r) =>
          r.sourceScreen !== report.sourceScreen ||
          r.destinationScreen !== report.destinationScreen,
      );
      return [...filtered, report];
    });
  }, []);
  const findReport = useCallback(
    (destinationScreen: string, sourceScreen?: string) => {
      return reports.find(
        (r) =>
          r.sourceScreen === sourceScreen &&
          r.destinationScreen === destinationScreen,
      );
    },
    [reports],
  );
  return (
    <GestureHandlerRootView style={{flex: 1}}>
      <ReportContext.Provider value={{ saveReport, findReport }}>
        <PerformanceProfiler
          onReportPrepared={onReportPrepared}
          logLevel={LogLevel.Debug}
        >
          <NavigationContainer>
            <Drawer.Navigator>
              <Drawer.Screen name="Drawer Screen A" component={DrawerScreenA} />
              <Drawer.Screen name="Drawer Screen B" component={DrawerScreenB} />
            </Drawer.Navigator>
          </NavigationContainer>
        </PerformanceProfiler>
      </ReportContext.Provider>
    </GestureHandlerRootView>
  );
};
const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 20,
    backgroundColor: '#283593',
  },
  label: {
    color: 'white',
    fontSize: 28,
  },
  text: {
    fontSize: 20,
    color: 'white',
    marginTop: 20,
  },
});
API reference
Check out the dedicated documentation for info about this library, API reference and more: Official react-native-performance-navigation-drawer documentation
Functions
| Function | Description | Platform support | 
|---|---|---|
| createDrawerNavigator | This utility wraps over the stock createDrawerNavigator, and allows you to profile how long it takes to render the screens hosted inside the different tabs. | All | 
Implementaiton details
- Render pass reports for navigating within the drawer navigator aren't currently generated on Vega due to a known issue with focus management in react-navigation's drawer navigator.
Supported Versions
| Package version | Based on | @amazon-devices/react-native-kepler version | 
|---|---|---|
| 3.0.0 | @shopify/react-native-performance-navigation-drawer v3.0.0 | 2.0.x | 
Additional resources
For information on additional libraries, see Supported Third-Party Libraries and Services.
Last updated: Sep 30, 2025

