Skip to content

Commit ff2b2cb

Browse files
committed
feat: expose functionality to start benchmarking manually
1 parent c7a0d95 commit ff2b2cb

File tree

6 files changed

+377
-39
lines changed

6 files changed

+377
-39
lines changed
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
import React, { useRef, useState } from "react";
2+
import { View, Text, Button, StyleSheet, Alert } from "react-native";
3+
import { FlashList, useBenchmark } from "@shopify/flash-list";
4+
5+
interface DataItem {
6+
id: string;
7+
title: string;
8+
value: number;
9+
}
10+
11+
const generateData = (count: number): DataItem[] => {
12+
return Array.from({ length: count }, (_, index) => ({
13+
id: `item-${index}`,
14+
title: `Item ${index}`,
15+
value: Math.floor(Math.random() * 100),
16+
}));
17+
};
18+
19+
const ManualBenchmarkExample = () => {
20+
const flashListRef = useRef<FlashList<DataItem>>(null);
21+
const [data] = useState(() => generateData(1000));
22+
const [benchmarkResult, setBenchmarkResult] = useState<string>("");
23+
24+
const [blankAreaTracker, { startBenchmark, isBenchmarkRunning }] =
25+
useBenchmark(
26+
flashListRef,
27+
(result) => {
28+
if (!result.interrupted) {
29+
setBenchmarkResult(result.formattedString || "No results");
30+
Alert.alert("Benchmark Complete", result.formattedString);
31+
}
32+
},
33+
{
34+
startManually: true,
35+
repeatCount: 3,
36+
speedMultiplier: 1.5,
37+
}
38+
);
39+
40+
const renderItem = ({ item }: { item: DataItem }) => (
41+
<View style={styles.item}>
42+
<Text style={styles.title}>{item.title}</Text>
43+
<Text style={styles.value}>Value: {item.value}</Text>
44+
</View>
45+
);
46+
47+
return (
48+
<View style={styles.container}>
49+
<View style={styles.header}>
50+
<Text style={styles.headerText}>Manual Benchmark Example</Text>
51+
<Button
52+
title={isBenchmarkRunning ? "Running..." : "Start Benchmark"}
53+
onPress={startBenchmark}
54+
disabled={isBenchmarkRunning}
55+
/>
56+
</View>
57+
58+
<FlashList
59+
ref={flashListRef}
60+
data={data}
61+
renderItem={renderItem}
62+
estimatedItemSize={80}
63+
keyExtractor={(item) => item.id}
64+
onBlankArea={blankAreaTracker}
65+
/>
66+
67+
{benchmarkResult ? (
68+
<View style={styles.resultContainer}>
69+
<Text style={styles.resultText}>{benchmarkResult}</Text>
70+
</View>
71+
) : null}
72+
</View>
73+
);
74+
};
75+
76+
const styles = StyleSheet.create({
77+
container: {
78+
flex: 1,
79+
backgroundColor: "#f5f5f5",
80+
},
81+
header: {
82+
padding: 16,
83+
backgroundColor: "white",
84+
borderBottomWidth: 1,
85+
borderBottomColor: "#e0e0e0",
86+
},
87+
headerText: {
88+
fontSize: 18,
89+
fontWeight: "bold",
90+
marginBottom: 8,
91+
},
92+
item: {
93+
backgroundColor: "white",
94+
padding: 16,
95+
marginHorizontal: 16,
96+
marginVertical: 8,
97+
borderRadius: 8,
98+
shadowColor: "#000",
99+
shadowOffset: { width: 0, height: 2 },
100+
shadowOpacity: 0.1,
101+
shadowRadius: 4,
102+
elevation: 3,
103+
},
104+
title: {
105+
fontSize: 16,
106+
fontWeight: "600",
107+
},
108+
value: {
109+
fontSize: 14,
110+
color: "#666",
111+
marginTop: 4,
112+
},
113+
resultContainer: {
114+
padding: 16,
115+
backgroundColor: "#e8f5e9",
116+
borderTopWidth: 1,
117+
borderTopColor: "#4caf50",
118+
},
119+
resultText: {
120+
fontSize: 12,
121+
fontFamily: "monospace",
122+
color: "#2e7d32",
123+
},
124+
});
125+
126+
export default ManualBenchmarkExample;
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
import React, { useRef, useState } from "react";
2+
import { View, Text, Button, StyleSheet, Alert, FlatList } from "react-native";
3+
import { useFlatListBenchmark } from "@shopify/flash-list";
4+
5+
interface DataItem {
6+
id: string;
7+
title: string;
8+
description: string;
9+
}
10+
11+
const generateData = (count: number): DataItem[] => {
12+
return Array.from({ length: count }, (_, index) => ({
13+
id: `item-${index}`,
14+
title: `Item ${index}`,
15+
description: `This is a description for item ${index}. It contains some text to make the item larger.`,
16+
}));
17+
};
18+
19+
const ManualFlatListBenchmarkExample = () => {
20+
const flatListRef = useRef<FlatList<DataItem>>(null);
21+
const [data] = useState(() => generateData(500));
22+
const [benchmarkResult, setBenchmarkResult] = useState<string>("");
23+
24+
const { startBenchmark, isBenchmarkRunning } = useFlatListBenchmark(
25+
flatListRef,
26+
(result) => {
27+
if (!result.interrupted) {
28+
setBenchmarkResult(result.formattedString || "No results");
29+
Alert.alert("FlatList Benchmark Complete", result.formattedString);
30+
}
31+
},
32+
{
33+
startManually: true,
34+
targetOffset: 10000, // Scroll to 10000 pixels
35+
repeatCount: 2,
36+
speedMultiplier: 2,
37+
}
38+
);
39+
40+
const renderItem = ({ item }: { item: DataItem }) => (
41+
<View style={styles.item}>
42+
<Text style={styles.title}>{item.title}</Text>
43+
<Text style={styles.description}>{item.description}</Text>
44+
</View>
45+
);
46+
47+
return (
48+
<View style={styles.container}>
49+
<View style={styles.header}>
50+
<Text style={styles.headerText}>Manual FlatList Benchmark Example</Text>
51+
<Text style={styles.subheader}>
52+
Tests native FlatList performance for comparison
53+
</Text>
54+
<Button
55+
title={isBenchmarkRunning ? "Running..." : "Start FlatList Benchmark"}
56+
onPress={startBenchmark}
57+
disabled={isBenchmarkRunning}
58+
/>
59+
</View>
60+
61+
<FlatList
62+
ref={flatListRef}
63+
data={data}
64+
renderItem={renderItem}
65+
keyExtractor={(item) => item.id}
66+
getItemLayout={(_, index) => ({
67+
length: 100,
68+
offset: 100 * index,
69+
index,
70+
})}
71+
/>
72+
73+
{benchmarkResult ? (
74+
<View style={styles.resultContainer}>
75+
<Text style={styles.resultTitle}>FlatList Results:</Text>
76+
<Text style={styles.resultText}>{benchmarkResult}</Text>
77+
</View>
78+
) : null}
79+
</View>
80+
);
81+
};
82+
83+
const styles = StyleSheet.create({
84+
container: {
85+
flex: 1,
86+
backgroundColor: "#f5f5f5",
87+
},
88+
header: {
89+
padding: 16,
90+
backgroundColor: "white",
91+
borderBottomWidth: 1,
92+
borderBottomColor: "#e0e0e0",
93+
},
94+
headerText: {
95+
fontSize: 18,
96+
fontWeight: "bold",
97+
marginBottom: 4,
98+
},
99+
subheader: {
100+
fontSize: 14,
101+
color: "#666",
102+
marginBottom: 12,
103+
},
104+
item: {
105+
backgroundColor: "white",
106+
padding: 16,
107+
marginHorizontal: 16,
108+
marginVertical: 8,
109+
borderRadius: 8,
110+
height: 84, // Fixed height for consistent scrolling
111+
shadowColor: "#000",
112+
shadowOffset: { width: 0, height: 2 },
113+
shadowOpacity: 0.1,
114+
shadowRadius: 4,
115+
elevation: 3,
116+
},
117+
title: {
118+
fontSize: 16,
119+
fontWeight: "600",
120+
},
121+
description: {
122+
fontSize: 14,
123+
color: "#666",
124+
marginTop: 4,
125+
},
126+
resultContainer: {
127+
padding: 16,
128+
backgroundColor: "#fff3e0",
129+
borderTopWidth: 1,
130+
borderTopColor: "#ff9800",
131+
},
132+
resultTitle: {
133+
fontSize: 14,
134+
fontWeight: "bold",
135+
marginBottom: 4,
136+
color: "#e65100",
137+
},
138+
resultText: {
139+
fontSize: 12,
140+
fontFamily: "monospace",
141+
color: "#bf360c",
142+
},
143+
});
144+
145+
export default ManualFlatListBenchmarkExample;

fixture/react-native/src/twitter/TwitterBenchmark.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
11
import React, { useRef } from "react";
2-
import { FlashList, useFlatListBenchmark } from "@shopify/flash-list";
2+
import { FlashList, useBenchmark } from "@shopify/flash-list";
33

44
import Twitter from "./Twitter";
55
import Tweet from "./models/Tweet";
66

77
const TwitterBenchmark = () => {
88
const ref = useRef<FlashList<Tweet>>(null);
9-
const [blankAreaTracker] = useFlatListBenchmark(
10-
// @ts-ignore - Type compatibility issue with useFlatListBenchmark
9+
const [blankAreaTracker] = useBenchmark(
1110
ref,
1211
(res) => {
1312
if (!res.interrupted) {
1413
// eslint-disable-next-line no-alert
1514
alert(res.formattedString);
1615
}
1716
},
18-
{ targetOffset: 200 * 100, speedMultiplier: 2, repeatCount: 5 }
17+
{ speedMultiplier: 2, repeatCount: 5 }
1918
);
2019

2120
// @ts-ignore - Type compatibility issue with ref passing

0 commit comments

Comments
 (0)