as

Settings
Sign out
Notifications
Alexa
Amazon Appstore
Ring
AWS
Documentation
Support
Contact Us
My Cases
Get Started
Design and Develop
Publish
Reference
Support

shopify-react-native-performance-lists-profiler

@amazon-devices/shopify__react-native-performance-lists-profiler is an extension library atop @shopify/react-native-performance-navigation that provides utilities for profiling the FlatList and FlashList components.

Installation

  1. Add the JavaScript library dependency in the package.json file:

    Copied to clipboard.

     "dependencies": {
     ...
     "@amazon-devices/react-navigation__native": "~2.0.0",
     "@amazon-devices/react-navigation__stack": "~2.0.0",
     "@amazon-devices/shopify__flash-list": "~2.0.0",
     "@shopify/react-native-performance-lists-profiler": "npm:@amazon-devices/shopify__react-native-performance-lists-profiler@~1.1.0",
     "@amazon-devices/keplerscript-turbomodule-api": "~1.0.0"
     },
    
  2. Reinstall dependencies using the npm install command.

Examples

Copied to clipboard.


import React, {
  createContext,
  ReactNode,
  useCallback,
  useContext,
  useState,
} from 'react';
import {
  Button,
  FlatList,
  ListRenderItem,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
} from 'react-native';
import { NavigationContainer } from '@amazon-devices/react-navigation__native';
import {
  createStackNavigator,
  StackScreenProps,
} from '@amazon-devices/react-navigation__stack';
import {
  FlashListPerformanceView,
  FlatListPerformanceView,
  ListsProfiler,
} from '@shopify/react-native-performance-lists-profiler';
import {
  FlashList,
  ListRenderItem as FlashListRenderItem,
} from '@amazon-devices/shopify__flash-list';

interface BlankArea {
  start: number;
  end: number;
}

interface ListsProfilerContextType {
  listName: string;
  tti: number | undefined;
  blankArea: BlankArea | undefined;
  resetContext: () => void;
  onInteractive: (tti: number, listName: string) => void;
  onBlankArea: (start: number, end: number, listName: string) => void;
}

const ListsProfilerContext = createContext<ListsProfilerContextType | null>(
  null,
);

interface ListsProfilerContextProviderProps {
  children: ReactNode;
}

const ListsProfilerContextProvider = ({
  children,
}: ListsProfilerContextProviderProps) => {
  const [listName, setListName] = useState('');
  const [tti, setTti] = useState<number>();
  const [blankArea, setBlankArea] = useState<BlankArea>();

  const resetContext = useCallback(() => {
    setListName('');
    setTti(undefined);
    setBlankArea(undefined);
  }, []);

  const onInteractive = useCallback((tti: number, listName: string) => {
    setTti(tti);
    setListName(listName);
  }, []);

  const onBlankArea = useCallback(
    (start: number, end: number, listName: string) => {
      setBlankArea({ start, end });
      setListName(listName);
    },
    [],
  );

  return (
    <ListsProfilerContext.Provider
      value={{
        listName,
        tti,
        blankArea,
        resetContext,
        onInteractive,
        onBlankArea,
      }}
    >
      {children}
    </ListsProfilerContext.Provider>
  );
};

type StackParamList = {
  FlashListScreen: undefined;
  FlatListScreen: undefined;
  HomeScreen: undefined;
};

const Stack = createStackNavigator<StackParamList>();

const NavigationTree = () => {
  const { onInteractive, onBlankArea } = useContext(
    ListsProfilerContext,
  ) as ListsProfilerContextType;

  return (
    <ListsProfiler onInteractive={onInteractive} onBlankArea={onBlankArea}>
      <NavigationContainer>
        <Stack.Navigator initialRouteName="HomeScreen">
          <Stack.Screen
            name="HomeScreen"
            component={HomeScreen}
            options={{ headerShown: false }}
          />
          <Stack.Screen name="FlatListScreen" component={FlatListScreen} />
          <Stack.Screen name="FlashListScreen" component={FlashListScreen} />
        </Stack.Navigator>
      </NavigationContainer>
    </ListsProfiler>
  );
};

const HomeScreen = ({
  navigation,
}: StackScreenProps<StackParamList, 'HomeScreen'>) => {
  const { resetContext } = useContext(
    ListsProfilerContext,
  ) as ListsProfilerContextType;

  const onNavigate =
    (screenName: 'FlatListScreen' | 'FlashListScreen') => () => {
      resetContext();
      navigation.navigate(screenName);
    };

  return (
    <View style={styles.container}>
      <Text style={styles.text}>FlatList Example</Text>
      <Button title="FlatListScreen" onPress={onNavigate('FlatListScreen')} />
      <Text style={styles.text}>FlashList Example</Text>
      <Button title="FlashListScreen" onPress={onNavigate('FlashListScreen')} />
    </View>
  );
};

export interface Item {
  bgColor: string;
  title: string;
  height: number;
}

const listData = Array.from({ length: 1000 }, (_, i) => ({
  title: `Item ${i + 1}`,
  bgColor: `#${Math.floor(Math.random() * 16777215).toString(16)}`,
  height: Math.floor(Math.random() * (140 - 60) + 60),
}));

interface ListItemProps {
  item: Item;
}

const ListItem = ({ item }: ListItemProps) => {
  return (
    <TouchableOpacity
      style={{ backgroundColor: item.bgColor, height: item.height }}
    >
      <Text style={styles.itemText}>{item.title}</Text>
    </TouchableOpacity>
  );
};

const DataDisplay = () => {
  const { listName, tti, blankArea } = useContext(
    ListsProfilerContext,
  ) as ListsProfilerContextType;

  return (
    <View style={styles.display}>
      <Text style={styles.text}>List name: {listName}</Text>
      <View style={styles.spacer} />
      <Text style={styles.text}>TTI: {tti ?? 'n/a'}</Text>
      <View style={styles.spacer} />
      <Text style={styles.text}>
        Blank area:{' '}
        {blankArea ? JSON.stringify(blankArea, undefined, 0) : 'n/a'}
      </Text>
    </View>
  );
};

const FlatListScreen = () => {
  const renderItem: ListRenderItem<Item> = useCallback(
    ({ item }) => <ListItem item={item} />,
    [],
  );

  return (
    <View style={styles.listContainer}>
      <DataDisplay />
      <FlatListPerformanceView listName="flatlist">
        <FlatList data={listData} renderItem={renderItem} />
      </FlatListPerformanceView>
    </View>
  );
};

const FlashListScreen = () => {
  const renderItem: FlashListRenderItem<Item> = useCallback(
    ({ item }) => <ListItem item={item} />,
    [],
  );

  return (
    <View style={styles.listContainer}>
      <DataDisplay />
      <FlashListPerformanceView listName="flashlist">
        <FlashList data={listData} renderItem={renderItem} />
      </FlashListPerformanceView>
    </View>
  );
};

export const App = () => {
  return (
    <ListsProfilerContextProvider>
      <NavigationTree />
    </ListsProfilerContextProvider>
  );
};

const styles = StyleSheet.create({
  container: {
    backgroundColor: '#fff',
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
  display: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
    paddingVertical: 20,
  },
  itemText: {
    fontSize: 24,
    color: '#fff',
    fontWeight: '500',
  },
  listContainer: {
    flex: 1,
  },
  spacer: {
    width: 32,
  },
  text: {
    fontSize: 30,
    fontWeight: '500',
  },
});

API reference

See the documentation for information about this library and API reference: Official react-native-performance-lists-profiler documentation.

Components

Component Description
ListsProfiler Collects the performance metrics. Mount high in the app tree.
FlatListPerformanceView A wrapper for the FlatList component that enables performance metrics collection.
FlashListPerformanceView A wrapper for the FlashList component that enables performance metrics collection.

ListsProfiler props

Prop Description
onInteractive Callback triggered when the profiled list becomes interactive. Use to process the profiling results in a custom manner. The prop has two parameters: TTI - Represents the time-to-interactive, listName - Name of the list defined in the performance view.
onBlankArea Callback triggered on each frame the list scrolls, even when no blank spaces exists. Processes the profiling results in a custom manner. The prop has three parameters:
offsetStart - Visible blank space on top of the screen (while going up). Visible for values higher than 0.
offsetEnd - Visible blank space at the end of the screen (while going down). Visible for values higher than 0.
listName - Name of the list defined in the performance view.

FlatListPerformanceView props

Prop Description
listName The name of the list used in the callbacks onInteractive and onBlankArea.
onInteractive Callback triggered when the profiled list becomes interactive. Used directly on FlatListPerformanceView if you want to avoid using ListsProfiler. The prop has two parameters: TTI - Represents the time-to-interactive.
listName - Name of the list defined in FlatListPerformanceView.
onBlankArea Callback triggered on each frame the list scrolls, even when no blank spaces exists. Used directly on FlatListPerformanceView if you want to avoid using ListsProfiler. The prop has three parameters: offsetStart - Visible blank space on top of the screen (while going up). Visible for values higher than 0.
offsetEnd - Visible blank space at the end of the screen (while going down). Visible for values higher than 0.
listName - Name of the list defined in FlatListPerformanceView.

FlashListPerformanceView props

Prop Description Platform support
listName The name of the list used in the callbacks onInteractive and onBlankArea All

Known issues and limitations

The documentation of the upstream version of the library mistakenly states that FlashListPerformanceView API is the same as FlatListPerformanceView. You can only useonInteractive and onBlankArea directly with FlatListPerformanceView.

Supported versions

Package name Amazon NPM library version Vega OS build number Vega SDK version Release notes
@amazon-devices/shopify__react-native-performance-lists-profiler 2.0.1+4.1.2 OS 1.1 (201010438050) 0.20  

Supported Third-Party Libraries and Services.


Last updated: Sep 30, 2025