Optimize flattenStyle for nested style arrays#57203
Open
tarikfp wants to merge 1 commit into
Open
Conversation
|
@Abbondanzo has imported this pull request. If you are a Meta employee, you can view this in D108616011. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Benchmark proof
External reproducible benchmark app:
https://github.com/tarikfp/rn-style-flatten-benchmark
Latest
yarn bench:comparefrom the benchmark repo compares React Nativemainat066c0d8bd8against this branch at81b5bc26b6:This is not a blanket claim that every React Native screen becomes 50%+ faster. It is targeted to the
flattenStylepath when composed components pass nested style arrays.Validation
yarn testin benchmark app repoyarn lintin benchmark app repoyarn workspace style-flatten-benchmark-app tsc --noEmityarn bench:compareyarn test packages/react-native/Libraries/StyleSheet/__tests__/flattenStyle-test.js --runInBandin the React Native checkoutDraft while broader upstream validation is gathered.
Affected areas
flattenStyleis not only the publicStyleSheet.flattenhelper. Core React Native components call it when they need to read or normalize style props before passing work further down:Textuses it inpackages/react-native/Libraries/Text/Text.js:188before normalizing text style values such as numericfontWeightand text selection-related props.Imageuses it on both platforms:Image.ios.js:141readsobjectFit,resizeMode, andtintColor;Image.android.js:310readsobjectFitandresizeModebefore building native props.ImageBackgrounduses it inpackages/react-native/Libraries/Image/ImageBackground.js:72before splitting size-related style values between the wrapper view and inner image.TextInputuses it inpackages/react-native/Libraries/Components/TextInput/TextInput.js:655while preserving the original style when possible, but still flattening to normalize text style overrides.TouchableOpacityuses it inpackages/react-native/Libraries/Components/Touchable/TouchableOpacity.js:260and:364to read opacity fromstylewhen setting and updating its animated opacity.ScrollViewuses it inpackages/react-native/Libraries/Components/ScrollView/ScrollView.js:1663for development-time layout warnings and in:1850when splitting outer and inner layout props around refresh controls.Animated.ScrollViewuses the same split path inpackages/react-native/Libraries/Animated/components/AnimatedScrollView.js:94.packages/react-native/Libraries/Animated/nodes/AnimatedProps.js:62and:157, and the newer memo hook uses it inpackages/react-native/src/private/animated/createAnimatedPropsMemoHook.js:125, so nested style arrays also matter for animated style props.packages/react-native/Libraries/ReactNative/ReactFabricPublicInstance/ReactNativeAttributePayload.js:186and:195before diffing array style props.ElementProperties.js:43andElementBox.js:34, and React DevTools receives it as the React Native style resolver fromsetUpReactDevTools.js:74.That is why the benchmark focuses on nested style arrays instead of claiming every render gets faster. The change helps when those call sites receive styles composed like
style={[base, condition && extra, [override]]}.Changelog:
[GENERAL] [CHANGED] - Make
flattenStyleavoid extra intermediate objects when flattening nested style arrays.Test Plan:
yarn test packages/react-native/Libraries/StyleSheet/__tests__/flattenStyle-test.js --runInBand.yarn test,yarn lint, andyarn workspace style-flatten-benchmark-app tsc --noEmit.yarn bench:comparein the benchmark app repo. The latest saved result compares React Nativemainat066c0d8bd8with this branch at81b5bc26b6and shows the nested style-array cases improving from294.79 msto98.73 msand from278.54 msto122.06 ms.mainbuild and this branch side by side.