diff --git a/packages/react-native/Libraries/Components/View/__tests__/ViewProps-benchmark-itest.js b/packages/react-native/Libraries/Components/View/__tests__/ViewProps-benchmark-itest.js new file mode 100644 index 000000000000..0544b9115c2b --- /dev/null +++ b/packages/react-native/Libraries/Components/View/__tests__/ViewProps-benchmark-itest.js @@ -0,0 +1,172 @@ +/** + * 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. + * + * @fantom_flags enableCppPropsIteratorSetter:* + * @flow strict-local + * @format + */ + +import '@react-native/fantom/src/setUpDefaultReactNativeEnvironment'; + +import * as Fantom from '@react-native/fantom'; +import * as React from 'react'; +import {View} from 'react-native'; + +let root; +let initialTree: React.MixedElement; +let updatedTree: React.MixedElement; + +function buildViewsWithFullPropBag( + count: number, + variant: 'a' | 'b', +): React.MixedElement { + const accent = variant === 'a' ? 'blue' : 'red'; + const offset = variant === 'a' ? 0 : 1; + const children = []; + for (let i = 0; i < count; i++) { + children.push( + , + ); + } + return ( + + {children} + + ); +} + +function buildViewsWithSinglePropDelta( + count: number, + toggle: boolean, +): React.MixedElement { + const children = []; + for (let i = 0; i < count; i++) { + children.push( + , + ); + } + return ( + + {children} + + ); +} + +Fantom.unstable_benchmark + .suite('Props construction') + .test.each( + [100, 1000], + n => `mount ${n.toString()} views with full prop bag`, + () => { + Fantom.runTask(() => root.render(initialTree)); + }, + n => ({ + beforeAll: () => { + initialTree = buildViewsWithFullPropBag(n, 'a'); + }, + beforeEach: () => { + root = Fantom.createRoot(); + }, + afterEach: () => { + root.destroy(); + }, + }), + ) + .test.each( + [100, 1000], + n => `re-render ${n.toString()} views with full prop swap (cloneProps)`, + () => { + Fantom.runTask(() => root.render(updatedTree)); + }, + n => ({ + beforeAll: () => { + initialTree = buildViewsWithFullPropBag(n, 'a'); + updatedTree = buildViewsWithFullPropBag(n, 'b'); + }, + beforeEach: () => { + root = Fantom.createRoot(); + Fantom.runTask(() => root.render(initialTree)); + }, + afterEach: () => { + root.destroy(); + }, + }), + ) + .test.each( + [100, 1000], + n => `re-render ${n.toString()} views with single-prop delta (cloneProps)`, + () => { + Fantom.runTask(() => root.render(updatedTree)); + }, + n => ({ + beforeAll: () => { + initialTree = buildViewsWithSinglePropDelta(n, false); + updatedTree = buildViewsWithSinglePropDelta(n, true); + }, + beforeEach: () => { + root = Fantom.createRoot(); + Fantom.runTask(() => root.render(initialTree)); + }, + afterEach: () => { + root.destroy(); + }, + }), + );