@samitouri / QOS-React / commits / 0061ca6cf4

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);