as

Settings
Sign out
Notifications
Alexa
Amazon Appstore
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 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

Check out the dedicated documentation for info about this library, API reference and more: Official react-native-performance-lists-profiler documentation.

Components

Component Description
ListsProfiler A component used for collecting the performance metrics. Mount high in the app tree
FlatListPerformanceView A wrapper for FlatList component that enables performance metrics collection
FlashListPerformanceView A wrapper for 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. Used to process 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

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. Uused 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). IVisible 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

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

Implementation details

  • The documentation of the upstream version of the library mistakingly 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  

Additional resources

For information on additional libraries, see Supported Third-Party Libraries and Services.


Last updated: Sep 30, 2025