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
-
Add the JavaScript library dependency in the
package.jsonfile:"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" }, -
Reinstall dependencies using the
npm installcommand.
Examples
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 |
Related topics
Supported Third-Party Libraries and Services.
Last updated: Sep 30, 2025

