Create basic benchmark for Animated (#52874)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/52874

Changelog: [internal]

This creates a basic benchmark for the Animated API, which shows that **using Animated**, even without setting up animations, **makes rendering 3x slower** (similar when setting up a JS driven animation), but **6x slower when it sets up a native animation.**

Baseline:
### Animated (mode 🚀) ###

| (index) | Task name                                                                    | Latency average (ns)  | Latency median (ns)     | Throughput average (ops/s) | Throughput median (ops/s) | Samples |
| ------- | ---------------------------------------------------------------------------- | --------------------- | ----------------------- | -------------------------- | ------------------------- | ------- |
| 0       | 'render 1 views'                                                             | '85320.76 ± 1.27%'    | '82484.00'              | '11994 ± 0.09%'            | '12124'                   | 11721   |
| 1       | 'render 10 views'                                                            | '399462.22 ± 1.03%'   | '387702.00'             | '2552 ± 0.29%'             | '2579'                    | 2505    |
| 2       | 'render 100 views'                                                           | '3317795.78 ± 0.90%'  | '3232351.00 ± 70.00'    | '303 ± 0.74%'              | '309'                     | 302     |
| 3       | 'render 1 animated views (without no animations set up)'                     | '172534.31 ± 0.67%'   | '168423.00'             | '5874 ± 0.14%'             | '5937'                    | 5796    |
| 4       | 'render 10 animated views (without no animations set up)'                    | '1050582.87 ± 0.63%'  | '1031899.00 ± 20.00'    | '957 ± 0.37%'              | '969'                     | 952     |
| 5       | 'render 100 animated views (without no animations set up)'                   | '9255133.10 ± 1.06%'  | '8990333.00'            | '108 ± 0.94%'              | '111'                     | 109     |
| 6       | 'render 1 animated views (with a single animation set up - JS driven)'       | '203422.03 ± 0.50%'   | '198478.00'             | '4966 ± 0.17%'             | '5038'                    | 4916    |
| 7       | 'render 10 animated views (with a single animation set up - JS driven)'      | '1305600.39 ± 0.37%'  | '1288088.00 ± 15.00'    | '768 ± 0.30%'              | '776'                     | 766     |
| 8       | 'render 100 animated views (with a single animation set up - JS driven)'     | '12084658.14 ± 1.51%' | '11854181.00 ± 8493.00' | '83 ± 1.27%'               | '84'                      | 84      |
| 9       | 'render 1 animated views (with a single animation set up - native driven)'   | '313494.69 ± 0.32%'   | '308673.00'             | '3206 ± 0.19%'             | '3240'                    | 3190    |
| 10      | 'render 10 animated views (with a single animation set up - native driven)'  | '2223507.22 ± 0.50%'  | '2184839.00 ± 70.00'    | '451 ± 0.41%'              | '458'                     | 450     |
| 11      | 'render 100 animated views (with a single animation set up - native driven)' | '21352575.02 ± 0.71%' | '21239136.00 ± 2824.00' | '47 ± 0.69%'               | '47'                      | 64      |

Reviewed By: christophpurrer

Differential Revision: D79085920

fbshipit-source-id: 1dc13208da49cc325995f3455eaf86c4eb1e4d47
This commit is contained in:
Rubén Norte
2025-07-28 10:02:25 -07:00
committed by Facebook GitHub Bot
parent 797d14da9e
commit d2fa1cd900
@@ -0,0 +1,133 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/
import '@react-native/fantom/src/setUpDefaultReactNativeEnvironment';
import * as Fantom from '@react-native/fantom';
import * as React from 'react';
import {Animated, View, useAnimatedValue} from 'react-native';
function MyApp() {
return (
<View
style={[
{
width: 100,
height: 100,
opacity: 1,
},
]}
/>
);
}
function MyAnimatedApp() {
return (
<Animated.View
style={[
{
width: 100,
height: 100,
opacity: 1,
},
]}
/>
);
}
function MyAnimatedAppWithAnimation() {
const opacity = useAnimatedValue(1);
return (
<Animated.View
style={[
{
width: 100,
height: 100,
opacity,
},
]}
/>
);
}
function MyAnimatedAppWithNativeAnimation() {
const opacity = useAnimatedValue(1, {useNativeDriver: true});
return (
<Animated.View
style={[
{
width: 100,
height: 100,
opacity,
},
]}
/>
);
}
const ARGS = [1, 10, 100];
let root = Fantom.createRoot();
let element: React.MixedElement;
function renderElement() {
Fantom.runTask(() => root.render(element));
}
function getOptions(
numberOfComponents: number,
Component: React.ComponentType<{}>,
): Fantom.BenchmarkTestOptions {
return {
beforeAll: () => {
element = (
<>
{Array.from({length: numberOfComponents}, (_, i) => (
<Component key={i} />
))}
</>
);
},
beforeEach: () => {
Fantom.runTask(() => root.render(<></>));
},
};
}
Fantom.unstable_benchmark
.suite('Animated')
.test.each(
ARGS,
n => `render ${n} views`,
renderElement,
n => getOptions(n, MyApp),
)
.test.each(
ARGS,
n => `render ${n} animated views (without animations set up)`,
renderElement,
n => getOptions(n, MyAnimatedApp),
)
.test.each(
ARGS,
n =>
`render ${n} animated views (with a single animation set up - JS driven)`,
renderElement,
n => getOptions(n, MyAnimatedAppWithAnimation),
)
.test.each(
ARGS,
n =>
`render ${n} animated views (with a single animation set up - native driven)`,
renderElement,
n => getOptions(n, MyAnimatedAppWithNativeAnimation),
);