Add early return to diffProperties (#28842)
## Summary This PR adds early return to the `diff` function. We don't need to go through all the entries of `nextProps`, process and deep-diff the values if `nextProps` is the same object as `prevProps`. Roughly 6% of all `diffProperties` calls can be skipped. ## How did you test this change? RNTester.
Dmytro Rykun committed
Apr 18, 2024 at 17:24 UTC
0061ca6cf47c5124d2ebe708481fb03da9e8e267
9 files changed
+16
packages/react-native-renderer/src/ReactNativeAttributePayload.js
+7
@@ -14,6 +14,8 @@ import {
14
} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface';
15
import isArray from 'shared/isArray';
16
17
+import {enableEarlyReturnForPropDiffing} from 'shared/ReactFeatureFlags';
18
+
19
import type {AttributeConfiguration} from './ReactNativeTypes';
20
21
const emptyObject = {};
@@ -483,6 +485,11 @@ export function diff(
485
nextProps: Object,
486
validAttributes: AttributeConfiguration,
487
): null | Object {
488
+ if (enableEarlyReturnForPropDiffing) {
489
+ if (prevProps === nextProps) {
490
+ return null; // no change
491
+ }
492
+ }
493
return diffProperties(
494
null, // updatePayload
495
prevProps,
packages/shared/ReactFeatureFlags.js
+2
@@ -119,6 +119,8 @@ export const passChildrenWhenCloningPersistedNodes = false;
119
120
export const enableServerComponentLogs = __EXPERIMENTAL__;
121
122
+export const enableEarlyReturnForPropDiffing = false;
123
+
124
/**
125
* Enables an expiration time for retry lanes to avoid starvation.
126
*/
packages/shared/forks/ReactFeatureFlags.native-fb-dynamic.js
+1
@@ -20,6 +20,7 @@
20
export const alwaysThrottleRetries = __VARIANT__;
21
export const consoleManagedByDevToolsDuringStrictMode = __VARIANT__;
22
export const enableAsyncActions = __VARIANT__;
23
+export const enableEarlyReturnForPropDiffing = __VARIANT__;
24
export const enableComponentStackLocations = __VARIANT__;
25
export const enableDeferRootSchedulingToMicrotask = __VARIANT__;
26
export const enableInfiniteRenderLoopDetection = __VARIANT__;
packages/shared/forks/ReactFeatureFlags.native-fb.js
+1
@@ -22,6 +22,7 @@ export const {
22
alwaysThrottleRetries,
23
consoleManagedByDevToolsDuringStrictMode,
24
enableAsyncActions,
25
+ enableEarlyReturnForPropDiffing,
26
enableComponentStackLocations,
27
enableDeferRootSchedulingToMicrotask,
28
enableInfiniteRenderLoopDetection,
packages/shared/forks/ReactFeatureFlags.native-oss.js
+1
@@ -101,6 +101,7 @@ export const allowConcurrentByDefault = false;
101
export const enableTransitionTracing = false;
102
export const enableDO_NOT_USE_disableStrictPassiveEffect = false;
103
export const passChildrenWhenCloningPersistedNodes = false;
104
+export const enableEarlyReturnForPropDiffing = false;
105
106
// Profiling Only
107
export const enableProfilerTimer = __PROFILE__;
packages/shared/forks/ReactFeatureFlags.test-renderer.js
+1
@@ -76,6 +76,7 @@ export const disableClientCache = true;
76
export const enableServerComponentKeys = true;
77
export const enableServerComponentLogs = true;
78
export const enableInfiniteRenderLoopDetection = false;
79
+export const enableEarlyReturnForPropDiffing = false;
80
81
// TODO: This must be in sync with the main ReactFeatureFlags file because
82
// the Test Renderer's value must be the same as the one used by the
packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js
+1
@@ -87,6 +87,7 @@ export const disableLegacyMode = false;
87
export const disableDOMTestUtils = false;
88
89
export const disableDefaultPropsExceptForClasses = false;
90
+export const enableEarlyReturnForPropDiffing = false;
91
92
// Flow magic to verify the exports of this file match the original version.
93
((((null: any): ExportsType): FeatureFlagsType): ExportsType);
packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
+1
@@ -87,6 +87,7 @@ export const disableLegacyMode = false;
87
export const disableDOMTestUtils = false;
88
89
export const disableDefaultPropsExceptForClasses = false;
90
+export const enableEarlyReturnForPropDiffing = false;
91
92
// Flow magic to verify the exports of this file match the original version.
93
((((null: any): ExportsType): FeatureFlagsType): ExportsType);
packages/shared/forks/ReactFeatureFlags.www.js
+1
@@ -117,6 +117,7 @@ export const disableStringRefs = false;
117
export const disableLegacyMode = __EXPERIMENTAL__;
118
119
export const disableDOMTestUtils = false;
120
+export const enableEarlyReturnForPropDiffing = false;
121
122
// Flow magic to verify the exports of this file match the original version.
123
((((null: any): ExportsType): FeatureFlagsType): ExportsType);