Skip to content

Commit 9c35a5a

Browse files
Bartlomiej Bloniarzfacebook-github-bot
authored andcommitted
Add Performance Test example to rn-tester Animation Backend
Summary: Adds a new performance test example to the Animation Backend section in rn-tester. The example renders a grid of animated views to stress-test the animation backend. Changelog: [Internal] Differential Revision: D104053337
1 parent 0882a71 commit 9c35a5a

2 files changed

Lines changed: 149 additions & 1 deletion

File tree

packages/rn-tester/js/examples/AnimationBackend/AnimationBackendIndex.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import type {RNTesterModule} from '../../types/RNTesterTypes';
1212

1313
import PlaygroundExample from './ChessboardExample';
14+
import PerformanceTestExample from './PerformanceTestExample';
1415
import SwipeableListExample from './SwipeableListExample';
1516
import * as ReactNativeFeatureFlags from 'react-native/src/private/featureflags/ReactNativeFeatureFlags';
1617

@@ -25,5 +26,7 @@ export default {
2526
category: 'UI',
2627
description: `Examples demonstrating the Animation Backend for layout-updating animations. ${canUseBackend ? '' : 'You need to enable c++ Animated and the Animation Backend to see these examples.'}`,
2728
showIndividualExamples: true,
28-
examples: canUseBackend ? [PlaygroundExample, SwipeableListExample] : [],
29+
examples: canUseBackend
30+
? [PlaygroundExample, SwipeableListExample, PerformanceTestExample]
31+
: [],
2932
} as RNTesterModule;
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow strict-local
8+
* @format
9+
*/
10+
11+
import type {RNTesterModuleExample} from '../../types/RNTesterTypes';
12+
13+
import * as React from 'react';
14+
import {Animated, StyleSheet, Text, View} from 'react-native';
15+
import * as ReactNativeFeatureFlags from 'react-native/src/private/featureflags/ReactNativeFeatureFlags';
16+
17+
const optimizedAnimatedPropUpdatesEnabled =
18+
ReactNativeFeatureFlags.optimizedAnimatedPropUpdates();
19+
20+
function FlagIndicator(): React.Node {
21+
return (
22+
<View style={styles.flagRow}>
23+
<Text style={styles.flagLabel}>optimizedAnimatedPropUpdates:</Text>
24+
<Text
25+
style={[
26+
styles.flagValue,
27+
optimizedAnimatedPropUpdatesEnabled ? styles.flagOn : styles.flagOff,
28+
]}>
29+
{optimizedAnimatedPropUpdatesEnabled ? 'ON' : 'OFF'}
30+
</Text>
31+
</View>
32+
);
33+
}
34+
35+
const ROWS = 20;
36+
const COLS = 10;
37+
const SIZE = 35;
38+
39+
function PerformanceTest() {
40+
const animatedValue = React.useRef(new Animated.Value(0)).current;
41+
42+
React.useEffect(() => {
43+
const animation = Animated.loop(
44+
Animated.sequence([
45+
Animated.timing(animatedValue, {
46+
toValue: 1,
47+
duration: 500,
48+
useNativeDriver: true,
49+
}),
50+
Animated.timing(animatedValue, {
51+
toValue: 0,
52+
duration: 500,
53+
useNativeDriver: true,
54+
}),
55+
]),
56+
);
57+
animation.start();
58+
return () => animation.stop();
59+
}, [animatedValue]);
60+
61+
const backgroundColor = animatedValue.interpolate({
62+
inputRange: [0, 1],
63+
outputRange: ['red', 'lime'],
64+
});
65+
66+
const borderRadius = animatedValue.interpolate({
67+
inputRange: [0, 1],
68+
outputRange: [0, 25],
69+
});
70+
71+
// Approximation of Math.pow(2, sv * 3 + 4.5) with piecewise linear interpolation
72+
const perspective = animatedValue.interpolate({
73+
inputRange: [0, 0.25, 0.5, 0.75, 1],
74+
outputRange: [22.63, 38.05, 64, 107.63, 181.02],
75+
});
76+
77+
const animatedStyle = {
78+
borderRadius,
79+
backgroundColor,
80+
transform: [{perspective}, {rotateY: '45deg'}],
81+
};
82+
83+
return (
84+
<View style={styles.container}>
85+
<FlagIndicator />
86+
{new Array<void>(ROWS).fill().map((_row, i) => (
87+
<View key={i} style={styles.row}>
88+
{new Array<void>(COLS).fill().map((_col, j) => (
89+
<Animated.View key={j} style={[styles.box, animatedStyle]} />
90+
))}
91+
</View>
92+
))}
93+
</View>
94+
);
95+
}
96+
97+
const styles = StyleSheet.create({
98+
container: {
99+
flex: 1,
100+
alignItems: 'center',
101+
justifyContent: 'center',
102+
},
103+
row: {
104+
flexDirection: 'row',
105+
justifyContent: 'center',
106+
},
107+
box: {
108+
backgroundColor: 'navy',
109+
borderColor: 'pink',
110+
borderWidth: 1,
111+
width: SIZE,
112+
height: SIZE,
113+
},
114+
flagRow: {
115+
flexDirection: 'row',
116+
alignItems: 'center',
117+
paddingVertical: 8,
118+
paddingHorizontal: 8,
119+
marginBottom: 4,
120+
backgroundColor: '#f3f4f6',
121+
borderRadius: 4,
122+
},
123+
flagLabel: {
124+
fontSize: 12,
125+
fontWeight: 'bold',
126+
marginRight: 8,
127+
},
128+
flagValue: {
129+
fontSize: 12,
130+
fontWeight: 'bold',
131+
},
132+
flagOn: {
133+
color: '#16a34a',
134+
},
135+
flagOff: {
136+
color: '#dc2626',
137+
},
138+
});
139+
140+
export default {
141+
title: 'Performance Test',
142+
name: 'performance-test',
143+
description: 'Test out new features and ideas.',
144+
render: (): React.Node => <PerformanceTest />,
145+
} as RNTesterModuleExample;

0 commit comments

Comments
 (0)