Skip to content

Commit 48cda4a

Browse files
committed
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. DiffTrain build for commit 0061ca6.
1 parent f07367a commit 48cda4a

File tree

7 files changed

+162
-120
lines changed

7 files changed

+162
-120
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
36e62c6034281f23e5eb5aac776f5835faf06bfb
1+
0061ca6cf47c5124d2ebe708481fb03da9e8e267

compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-dev.fb.js

Lines changed: 41 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<96428d44939bb491570161921c41332c>>
10+
* @generated SignedSource<<84d884f07a1d5851f53652012b257860>>
1111
*/
1212

1313
"use strict";
@@ -2289,6 +2289,39 @@ to return true:wantsResponderID| |
22892289
ReactNativeBridgeEventPlugin: ReactNativeBridgeEventPlugin
22902290
});
22912291

2292+
// Re-export dynamic flags from the internal module.
2293+
var dynamicFlags = dynamicFlagsUntyped; // We destructure each value before re-exporting to avoid a dynamic look-up on
2294+
// the exports object every time a flag is read.
2295+
2296+
var alwaysThrottleRetries = dynamicFlags.alwaysThrottleRetries,
2297+
consoleManagedByDevToolsDuringStrictMode =
2298+
dynamicFlags.consoleManagedByDevToolsDuringStrictMode,
2299+
enableAsyncActions = dynamicFlags.enableAsyncActions,
2300+
enableEarlyReturnForPropDiffing =
2301+
dynamicFlags.enableEarlyReturnForPropDiffing,
2302+
enableComponentStackLocations =
2303+
dynamicFlags.enableComponentStackLocations,
2304+
enableDeferRootSchedulingToMicrotask =
2305+
dynamicFlags.enableDeferRootSchedulingToMicrotask,
2306+
enableInfiniteRenderLoopDetection =
2307+
dynamicFlags.enableInfiniteRenderLoopDetection,
2308+
enableRenderableContext = dynamicFlags.enableRenderableContext,
2309+
enableUnifiedSyncLane = dynamicFlags.enableUnifiedSyncLane,
2310+
passChildrenWhenCloningPersistedNodes =
2311+
dynamicFlags.passChildrenWhenCloningPersistedNodes,
2312+
useModernStrictMode = dynamicFlags.useModernStrictMode,
2313+
disableDefaultPropsExceptForClasses =
2314+
dynamicFlags.disableDefaultPropsExceptForClasses; // The rest of the flags are static for better dead code elimination.
2315+
var enableSchedulingProfiler = true;
2316+
var enableProfilerTimer = true;
2317+
var enableProfilerCommitHooks = true;
2318+
var enableProfilerNestedUpdatePhase = true;
2319+
var syncLaneExpirationMs = 250;
2320+
var transitionLaneExpirationMs = 5000;
2321+
var enableLazyContextPropagation = false;
2322+
var enableLegacyHidden = false;
2323+
var disableLegacyMode = false;
2324+
22922325
// Modules provided by RN:
22932326
var emptyObject$1 = {};
22942327
/**
@@ -2763,6 +2796,12 @@ to return true:wantsResponderID| |
27632796
);
27642797
}
27652798
function diff(prevProps, nextProps, validAttributes) {
2799+
if (enableEarlyReturnForPropDiffing) {
2800+
if (prevProps === nextProps) {
2801+
return null; // no change
2802+
}
2803+
}
2804+
27662805
return diffProperties(
27672806
null, // updatePayload
27682807
prevProps,
@@ -2966,37 +3005,6 @@ to return true:wantsResponderID| |
29663005
// where it would do it.
29673006
}
29683007

2969-
// Re-export dynamic flags from the internal module.
2970-
var dynamicFlags = dynamicFlagsUntyped; // We destructure each value before re-exporting to avoid a dynamic look-up on
2971-
// the exports object every time a flag is read.
2972-
2973-
var alwaysThrottleRetries = dynamicFlags.alwaysThrottleRetries,
2974-
consoleManagedByDevToolsDuringStrictMode =
2975-
dynamicFlags.consoleManagedByDevToolsDuringStrictMode,
2976-
enableAsyncActions = dynamicFlags.enableAsyncActions,
2977-
enableComponentStackLocations =
2978-
dynamicFlags.enableComponentStackLocations,
2979-
enableDeferRootSchedulingToMicrotask =
2980-
dynamicFlags.enableDeferRootSchedulingToMicrotask,
2981-
enableInfiniteRenderLoopDetection =
2982-
dynamicFlags.enableInfiniteRenderLoopDetection,
2983-
enableRenderableContext = dynamicFlags.enableRenderableContext,
2984-
enableUnifiedSyncLane = dynamicFlags.enableUnifiedSyncLane,
2985-
passChildrenWhenCloningPersistedNodes =
2986-
dynamicFlags.passChildrenWhenCloningPersistedNodes,
2987-
useModernStrictMode = dynamicFlags.useModernStrictMode,
2988-
disableDefaultPropsExceptForClasses =
2989-
dynamicFlags.disableDefaultPropsExceptForClasses; // The rest of the flags are static for better dead code elimination.
2990-
var enableSchedulingProfiler = true;
2991-
var enableProfilerTimer = true;
2992-
var enableProfilerCommitHooks = true;
2993-
var enableProfilerNestedUpdatePhase = true;
2994-
var syncLaneExpirationMs = 250;
2995-
var transitionLaneExpirationMs = 5000;
2996-
var enableLazyContextPropagation = false;
2997-
var enableLegacyHidden = false;
2998-
var disableLegacyMode = false;
2999-
30003008
var NoFlags$1 =
30013009
/* */
30023010
0;
@@ -30288,7 +30296,7 @@ to return true:wantsResponderID| |
3028830296
return root;
3028930297
}
3029030298

30291-
var ReactVersion = "19.0.0-canary-2d263258";
30299+
var ReactVersion = "19.0.0-canary-adfb7d73";
3029230300

3029330301
/*
3029430302
* The `'' + value` pattern (used in perf-sensitive code) throws for Symbol

compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-prod.fb.js

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<34dfa97c1577841a85cbb93e6d1aa9b7>>
10+
* @generated SignedSource<<d42756695dd6c4c7a24ede54b6a5902a>>
1111
*/
1212

1313
"use strict";
@@ -965,7 +965,25 @@ for (pluginName$jscomp$inline_249 in injectedNamesToPlugins$jscomp$inline_247)
965965
}
966966
}
967967
isOrderingDirty$jscomp$inline_248 && recomputePluginOrdering();
968-
var emptyObject$1 = {},
968+
var alwaysThrottleRetries = dynamicFlagsUntyped.alwaysThrottleRetries,
969+
consoleManagedByDevToolsDuringStrictMode =
970+
dynamicFlagsUntyped.consoleManagedByDevToolsDuringStrictMode,
971+
enableAsyncActions = dynamicFlagsUntyped.enableAsyncActions,
972+
enableEarlyReturnForPropDiffing =
973+
dynamicFlagsUntyped.enableEarlyReturnForPropDiffing,
974+
enableComponentStackLocations =
975+
dynamicFlagsUntyped.enableComponentStackLocations,
976+
enableDeferRootSchedulingToMicrotask =
977+
dynamicFlagsUntyped.enableDeferRootSchedulingToMicrotask,
978+
enableInfiniteRenderLoopDetection =
979+
dynamicFlagsUntyped.enableInfiniteRenderLoopDetection,
980+
enableRenderableContext = dynamicFlagsUntyped.enableRenderableContext,
981+
enableUnifiedSyncLane = dynamicFlagsUntyped.enableUnifiedSyncLane,
982+
passChildrenWhenCloningPersistedNodes =
983+
dynamicFlagsUntyped.passChildrenWhenCloningPersistedNodes,
984+
disableDefaultPropsExceptForClasses =
985+
dynamicFlagsUntyped.disableDefaultPropsExceptForClasses,
986+
emptyObject$1 = {},
969987
removedKeys = null,
970988
removedKeyCount = 0,
971989
deepDifferOptions = { unsafelyIgnoreFunctions: !0 };
@@ -1264,23 +1282,7 @@ function dispatchEvent(target, topLevelType, nativeEvent) {
12641282
}
12651283
});
12661284
}
1267-
var alwaysThrottleRetries = dynamicFlagsUntyped.alwaysThrottleRetries,
1268-
consoleManagedByDevToolsDuringStrictMode =
1269-
dynamicFlagsUntyped.consoleManagedByDevToolsDuringStrictMode,
1270-
enableAsyncActions = dynamicFlagsUntyped.enableAsyncActions,
1271-
enableComponentStackLocations =
1272-
dynamicFlagsUntyped.enableComponentStackLocations,
1273-
enableDeferRootSchedulingToMicrotask =
1274-
dynamicFlagsUntyped.enableDeferRootSchedulingToMicrotask,
1275-
enableInfiniteRenderLoopDetection =
1276-
dynamicFlagsUntyped.enableInfiniteRenderLoopDetection,
1277-
enableRenderableContext = dynamicFlagsUntyped.enableRenderableContext,
1278-
enableUnifiedSyncLane = dynamicFlagsUntyped.enableUnifiedSyncLane,
1279-
passChildrenWhenCloningPersistedNodes =
1280-
dynamicFlagsUntyped.passChildrenWhenCloningPersistedNodes,
1281-
disableDefaultPropsExceptForClasses =
1282-
dynamicFlagsUntyped.disableDefaultPropsExceptForClasses,
1283-
scheduleCallback$3 = Scheduler.unstable_scheduleCallback,
1285+
var scheduleCallback$3 = Scheduler.unstable_scheduleCallback,
12841286
cancelCallback$1 = Scheduler.unstable_cancelCallback,
12851287
shouldYield = Scheduler.unstable_shouldYield,
12861288
requestPaint = Scheduler.unstable_requestPaint,
@@ -7288,12 +7290,15 @@ function completeWork(current, workInProgress, renderLanes) {
72887290
: createChildNodeSet()),
72897291
appendAllChildrenToContainer(newChildSet, workInProgress, !1, !1));
72907292
b: {
7291-
oldProps = diffProperties(
7292-
null,
7293-
oldProps,
7294-
newProps,
7295-
renderLanes.canonical.viewConfig.validAttributes
7296-
);
7293+
oldProps =
7294+
enableEarlyReturnForPropDiffing && oldProps === newProps
7295+
? null
7296+
: diffProperties(
7297+
null,
7298+
oldProps,
7299+
newProps,
7300+
renderLanes.canonical.viewConfig.validAttributes
7301+
);
72977302
renderLanes.canonical.currentProps = newProps;
72987303
newProps = renderLanes.node;
72997304
if (current)
@@ -10597,7 +10602,7 @@ var roots = new Map(),
1059710602
devToolsConfig$jscomp$inline_1099 = {
1059810603
findFiberByHostInstance: getInstanceFromNode,
1059910604
bundleType: 0,
10600-
version: "19.0.0-canary-08aa6077",
10605+
version: "19.0.0-canary-7f7baf16",
1060110606
rendererPackageName: "react-native-renderer",
1060210607
rendererConfig: {
1060310608
getInspectorDataForInstance: getInspectorDataForInstance,
@@ -10640,7 +10645,7 @@ var internals$jscomp$inline_1366 = {
1064010645
scheduleRoot: null,
1064110646
setRefreshHandler: null,
1064210647
getCurrentFiber: null,
10643-
reconcilerVersion: "19.0.0-canary-08aa6077"
10648+
reconcilerVersion: "19.0.0-canary-7f7baf16"
1064410649
};
1064510650
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
1064610651
var hook$jscomp$inline_1367 = __REACT_DEVTOOLS_GLOBAL_HOOK__;

compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<d86bdae683e0b6b9649eb43c0d5548c4>>
10+
* @generated SignedSource<<64acec7be24561ecbf6d2eaf55e55d0a>>
1111
*/
1212

1313
"use strict";
@@ -969,7 +969,25 @@ for (pluginName$jscomp$inline_265 in injectedNamesToPlugins$jscomp$inline_263)
969969
}
970970
}
971971
isOrderingDirty$jscomp$inline_264 && recomputePluginOrdering();
972-
var emptyObject$1 = {},
972+
var alwaysThrottleRetries = dynamicFlagsUntyped.alwaysThrottleRetries,
973+
consoleManagedByDevToolsDuringStrictMode =
974+
dynamicFlagsUntyped.consoleManagedByDevToolsDuringStrictMode,
975+
enableAsyncActions = dynamicFlagsUntyped.enableAsyncActions,
976+
enableEarlyReturnForPropDiffing =
977+
dynamicFlagsUntyped.enableEarlyReturnForPropDiffing,
978+
enableComponentStackLocations =
979+
dynamicFlagsUntyped.enableComponentStackLocations,
980+
enableDeferRootSchedulingToMicrotask =
981+
dynamicFlagsUntyped.enableDeferRootSchedulingToMicrotask,
982+
enableInfiniteRenderLoopDetection =
983+
dynamicFlagsUntyped.enableInfiniteRenderLoopDetection,
984+
enableRenderableContext = dynamicFlagsUntyped.enableRenderableContext,
985+
enableUnifiedSyncLane = dynamicFlagsUntyped.enableUnifiedSyncLane,
986+
passChildrenWhenCloningPersistedNodes =
987+
dynamicFlagsUntyped.passChildrenWhenCloningPersistedNodes,
988+
disableDefaultPropsExceptForClasses =
989+
dynamicFlagsUntyped.disableDefaultPropsExceptForClasses,
990+
emptyObject$1 = {},
973991
removedKeys = null,
974992
removedKeyCount = 0,
975993
deepDifferOptions = { unsafelyIgnoreFunctions: !0 };
@@ -1268,23 +1286,7 @@ function dispatchEvent(target, topLevelType, nativeEvent) {
12681286
}
12691287
});
12701288
}
1271-
var alwaysThrottleRetries = dynamicFlagsUntyped.alwaysThrottleRetries,
1272-
consoleManagedByDevToolsDuringStrictMode =
1273-
dynamicFlagsUntyped.consoleManagedByDevToolsDuringStrictMode,
1274-
enableAsyncActions = dynamicFlagsUntyped.enableAsyncActions,
1275-
enableComponentStackLocations =
1276-
dynamicFlagsUntyped.enableComponentStackLocations,
1277-
enableDeferRootSchedulingToMicrotask =
1278-
dynamicFlagsUntyped.enableDeferRootSchedulingToMicrotask,
1279-
enableInfiniteRenderLoopDetection =
1280-
dynamicFlagsUntyped.enableInfiniteRenderLoopDetection,
1281-
enableRenderableContext = dynamicFlagsUntyped.enableRenderableContext,
1282-
enableUnifiedSyncLane = dynamicFlagsUntyped.enableUnifiedSyncLane,
1283-
passChildrenWhenCloningPersistedNodes =
1284-
dynamicFlagsUntyped.passChildrenWhenCloningPersistedNodes,
1285-
disableDefaultPropsExceptForClasses =
1286-
dynamicFlagsUntyped.disableDefaultPropsExceptForClasses,
1287-
scheduleCallback$3 = Scheduler.unstable_scheduleCallback,
1289+
var scheduleCallback$3 = Scheduler.unstable_scheduleCallback,
12881290
cancelCallback$1 = Scheduler.unstable_cancelCallback,
12891291
shouldYield = Scheduler.unstable_shouldYield,
12901292
requestPaint = Scheduler.unstable_requestPaint,
@@ -7554,12 +7556,15 @@ function completeWork(current, workInProgress, renderLanes) {
75547556
: createChildNodeSet()),
75557557
appendAllChildrenToContainer(newChildSet, workInProgress, !1, !1));
75567558
b: {
7557-
oldProps = diffProperties(
7558-
null,
7559-
oldProps,
7560-
newProps,
7561-
renderLanes.canonical.viewConfig.validAttributes
7562-
);
7559+
oldProps =
7560+
enableEarlyReturnForPropDiffing && oldProps === newProps
7561+
? null
7562+
: diffProperties(
7563+
null,
7564+
oldProps,
7565+
newProps,
7566+
renderLanes.canonical.viewConfig.validAttributes
7567+
);
75637568
renderLanes.canonical.currentProps = newProps;
75647569
newProps = renderLanes.node;
75657570
if (current)
@@ -11302,7 +11307,7 @@ var roots = new Map(),
1130211307
devToolsConfig$jscomp$inline_1179 = {
1130311308
findFiberByHostInstance: getInstanceFromNode,
1130411309
bundleType: 0,
11305-
version: "19.0.0-canary-42633113",
11310+
version: "19.0.0-canary-ef6bcf29",
1130611311
rendererPackageName: "react-native-renderer",
1130711312
rendererConfig: {
1130811313
getInspectorDataForInstance: getInspectorDataForInstance,
@@ -11358,7 +11363,7 @@ var roots = new Map(),
1135811363
scheduleRoot: null,
1135911364
setRefreshHandler: null,
1136011365
getCurrentFiber: null,
11361-
reconcilerVersion: "19.0.0-canary-42633113"
11366+
reconcilerVersion: "19.0.0-canary-ef6bcf29"
1136211367
});
1136311368
exports.createPortal = function (children, containerTag) {
1136411369
return createPortal$1(

compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<f5314f257c0eaf16ab8324449affda09>>
10+
* @generated SignedSource<<cda44a9b6dde6c0bc692dd0a256b0422>>
1111
*/
1212

1313
"use strict";
@@ -2688,6 +2688,8 @@ to return true:wantsResponderID| |
26882688
consoleManagedByDevToolsDuringStrictMode =
26892689
dynamicFlags.consoleManagedByDevToolsDuringStrictMode,
26902690
enableAsyncActions = dynamicFlags.enableAsyncActions,
2691+
enableEarlyReturnForPropDiffing =
2692+
dynamicFlags.enableEarlyReturnForPropDiffing,
26912693
enableComponentStackLocations =
26922694
dynamicFlags.enableComponentStackLocations,
26932695
enableDeferRootSchedulingToMicrotask =
@@ -3889,6 +3891,12 @@ to return true:wantsResponderID| |
38893891
);
38903892
}
38913893
function diff(prevProps, nextProps, validAttributes) {
3894+
if (enableEarlyReturnForPropDiffing) {
3895+
if (prevProps === nextProps) {
3896+
return null; // no change
3897+
}
3898+
}
3899+
38923900
return diffProperties(
38933901
null, // updatePayload
38943902
prevProps,
@@ -30742,7 +30750,7 @@ to return true:wantsResponderID| |
3074230750
return root;
3074330751
}
3074430752

30745-
var ReactVersion = "19.0.0-canary-f19a567c";
30753+
var ReactVersion = "19.0.0-canary-ad24d706";
3074630754

3074730755
/*
3074830756
* The `'' + value` pattern (used in perf-sensitive code) throws for Symbol

0 commit comments

Comments
 (0)