Skip to content

Commit

Permalink
Add early return to diffProperties (#28842)
Browse files Browse the repository at this point in the history
## 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.
  • Loading branch information
dmytrorykun committed Apr 18, 2024
1 parent f07367a commit 48cda4a
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 120 deletions.
Original file line number Diff line number Diff line change
@@ -1 +1 @@
36e62c6034281f23e5eb5aac776f5835faf06bfb
0061ca6cf47c5124d2ebe708481fb03da9e8e267
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @noflow
* @nolint
* @preventMunge
* @generated SignedSource<<96428d44939bb491570161921c41332c>>
* @generated SignedSource<<84d884f07a1d5851f53652012b257860>>
*/

"use strict";
Expand Down Expand Up @@ -2289,6 +2289,39 @@ to return true:wantsResponderID| |
ReactNativeBridgeEventPlugin: ReactNativeBridgeEventPlugin
});

// Re-export dynamic flags from the internal module.
var dynamicFlags = dynamicFlagsUntyped; // We destructure each value before re-exporting to avoid a dynamic look-up on
// the exports object every time a flag is read.

var alwaysThrottleRetries = dynamicFlags.alwaysThrottleRetries,
consoleManagedByDevToolsDuringStrictMode =
dynamicFlags.consoleManagedByDevToolsDuringStrictMode,
enableAsyncActions = dynamicFlags.enableAsyncActions,
enableEarlyReturnForPropDiffing =
dynamicFlags.enableEarlyReturnForPropDiffing,
enableComponentStackLocations =
dynamicFlags.enableComponentStackLocations,
enableDeferRootSchedulingToMicrotask =
dynamicFlags.enableDeferRootSchedulingToMicrotask,
enableInfiniteRenderLoopDetection =
dynamicFlags.enableInfiniteRenderLoopDetection,
enableRenderableContext = dynamicFlags.enableRenderableContext,
enableUnifiedSyncLane = dynamicFlags.enableUnifiedSyncLane,
passChildrenWhenCloningPersistedNodes =
dynamicFlags.passChildrenWhenCloningPersistedNodes,
useModernStrictMode = dynamicFlags.useModernStrictMode,
disableDefaultPropsExceptForClasses =
dynamicFlags.disableDefaultPropsExceptForClasses; // The rest of the flags are static for better dead code elimination.
var enableSchedulingProfiler = true;
var enableProfilerTimer = true;
var enableProfilerCommitHooks = true;
var enableProfilerNestedUpdatePhase = true;
var syncLaneExpirationMs = 250;
var transitionLaneExpirationMs = 5000;
var enableLazyContextPropagation = false;
var enableLegacyHidden = false;
var disableLegacyMode = false;

// Modules provided by RN:
var emptyObject$1 = {};
/**
Expand Down Expand Up @@ -2763,6 +2796,12 @@ to return true:wantsResponderID| |
);
}
function diff(prevProps, nextProps, validAttributes) {
if (enableEarlyReturnForPropDiffing) {
if (prevProps === nextProps) {
return null; // no change
}
}

return diffProperties(
null, // updatePayload
prevProps,
Expand Down Expand Up @@ -2966,37 +3005,6 @@ to return true:wantsResponderID| |
// where it would do it.
}

// Re-export dynamic flags from the internal module.
var dynamicFlags = dynamicFlagsUntyped; // We destructure each value before re-exporting to avoid a dynamic look-up on
// the exports object every time a flag is read.

var alwaysThrottleRetries = dynamicFlags.alwaysThrottleRetries,
consoleManagedByDevToolsDuringStrictMode =
dynamicFlags.consoleManagedByDevToolsDuringStrictMode,
enableAsyncActions = dynamicFlags.enableAsyncActions,
enableComponentStackLocations =
dynamicFlags.enableComponentStackLocations,
enableDeferRootSchedulingToMicrotask =
dynamicFlags.enableDeferRootSchedulingToMicrotask,
enableInfiniteRenderLoopDetection =
dynamicFlags.enableInfiniteRenderLoopDetection,
enableRenderableContext = dynamicFlags.enableRenderableContext,
enableUnifiedSyncLane = dynamicFlags.enableUnifiedSyncLane,
passChildrenWhenCloningPersistedNodes =
dynamicFlags.passChildrenWhenCloningPersistedNodes,
useModernStrictMode = dynamicFlags.useModernStrictMode,
disableDefaultPropsExceptForClasses =
dynamicFlags.disableDefaultPropsExceptForClasses; // The rest of the flags are static for better dead code elimination.
var enableSchedulingProfiler = true;
var enableProfilerTimer = true;
var enableProfilerCommitHooks = true;
var enableProfilerNestedUpdatePhase = true;
var syncLaneExpirationMs = 250;
var transitionLaneExpirationMs = 5000;
var enableLazyContextPropagation = false;
var enableLegacyHidden = false;
var disableLegacyMode = false;

var NoFlags$1 =
/* */
0;
Expand Down Expand Up @@ -30288,7 +30296,7 @@ to return true:wantsResponderID| |
return root;
}

var ReactVersion = "19.0.0-canary-2d263258";
var ReactVersion = "19.0.0-canary-adfb7d73";

/*
* The `'' + value` pattern (used in perf-sensitive code) throws for Symbol
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @noflow
* @nolint
* @preventMunge
* @generated SignedSource<<34dfa97c1577841a85cbb93e6d1aa9b7>>
* @generated SignedSource<<d42756695dd6c4c7a24ede54b6a5902a>>
*/

"use strict";
Expand Down Expand Up @@ -965,7 +965,25 @@ for (pluginName$jscomp$inline_249 in injectedNamesToPlugins$jscomp$inline_247)
}
}
isOrderingDirty$jscomp$inline_248 && recomputePluginOrdering();
var emptyObject$1 = {},
var alwaysThrottleRetries = dynamicFlagsUntyped.alwaysThrottleRetries,
consoleManagedByDevToolsDuringStrictMode =
dynamicFlagsUntyped.consoleManagedByDevToolsDuringStrictMode,
enableAsyncActions = dynamicFlagsUntyped.enableAsyncActions,
enableEarlyReturnForPropDiffing =
dynamicFlagsUntyped.enableEarlyReturnForPropDiffing,
enableComponentStackLocations =
dynamicFlagsUntyped.enableComponentStackLocations,
enableDeferRootSchedulingToMicrotask =
dynamicFlagsUntyped.enableDeferRootSchedulingToMicrotask,
enableInfiniteRenderLoopDetection =
dynamicFlagsUntyped.enableInfiniteRenderLoopDetection,
enableRenderableContext = dynamicFlagsUntyped.enableRenderableContext,
enableUnifiedSyncLane = dynamicFlagsUntyped.enableUnifiedSyncLane,
passChildrenWhenCloningPersistedNodes =
dynamicFlagsUntyped.passChildrenWhenCloningPersistedNodes,
disableDefaultPropsExceptForClasses =
dynamicFlagsUntyped.disableDefaultPropsExceptForClasses,
emptyObject$1 = {},
removedKeys = null,
removedKeyCount = 0,
deepDifferOptions = { unsafelyIgnoreFunctions: !0 };
Expand Down Expand Up @@ -1264,23 +1282,7 @@ function dispatchEvent(target, topLevelType, nativeEvent) {
}
});
}
var alwaysThrottleRetries = dynamicFlagsUntyped.alwaysThrottleRetries,
consoleManagedByDevToolsDuringStrictMode =
dynamicFlagsUntyped.consoleManagedByDevToolsDuringStrictMode,
enableAsyncActions = dynamicFlagsUntyped.enableAsyncActions,
enableComponentStackLocations =
dynamicFlagsUntyped.enableComponentStackLocations,
enableDeferRootSchedulingToMicrotask =
dynamicFlagsUntyped.enableDeferRootSchedulingToMicrotask,
enableInfiniteRenderLoopDetection =
dynamicFlagsUntyped.enableInfiniteRenderLoopDetection,
enableRenderableContext = dynamicFlagsUntyped.enableRenderableContext,
enableUnifiedSyncLane = dynamicFlagsUntyped.enableUnifiedSyncLane,
passChildrenWhenCloningPersistedNodes =
dynamicFlagsUntyped.passChildrenWhenCloningPersistedNodes,
disableDefaultPropsExceptForClasses =
dynamicFlagsUntyped.disableDefaultPropsExceptForClasses,
scheduleCallback$3 = Scheduler.unstable_scheduleCallback,
var scheduleCallback$3 = Scheduler.unstable_scheduleCallback,
cancelCallback$1 = Scheduler.unstable_cancelCallback,
shouldYield = Scheduler.unstable_shouldYield,
requestPaint = Scheduler.unstable_requestPaint,
Expand Down Expand Up @@ -7288,12 +7290,15 @@ function completeWork(current, workInProgress, renderLanes) {
: createChildNodeSet()),
appendAllChildrenToContainer(newChildSet, workInProgress, !1, !1));
b: {
oldProps = diffProperties(
null,
oldProps,
newProps,
renderLanes.canonical.viewConfig.validAttributes
);
oldProps =
enableEarlyReturnForPropDiffing && oldProps === newProps
? null
: diffProperties(
null,
oldProps,
newProps,
renderLanes.canonical.viewConfig.validAttributes
);
renderLanes.canonical.currentProps = newProps;
newProps = renderLanes.node;
if (current)
Expand Down Expand Up @@ -10597,7 +10602,7 @@ var roots = new Map(),
devToolsConfig$jscomp$inline_1099 = {
findFiberByHostInstance: getInstanceFromNode,
bundleType: 0,
version: "19.0.0-canary-08aa6077",
version: "19.0.0-canary-7f7baf16",
rendererPackageName: "react-native-renderer",
rendererConfig: {
getInspectorDataForInstance: getInspectorDataForInstance,
Expand Down Expand Up @@ -10640,7 +10645,7 @@ var internals$jscomp$inline_1366 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "19.0.0-canary-08aa6077"
reconcilerVersion: "19.0.0-canary-7f7baf16"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_1367 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @noflow
* @nolint
* @preventMunge
* @generated SignedSource<<d86bdae683e0b6b9649eb43c0d5548c4>>
* @generated SignedSource<<64acec7be24561ecbf6d2eaf55e55d0a>>
*/

"use strict";
Expand Down Expand Up @@ -969,7 +969,25 @@ for (pluginName$jscomp$inline_265 in injectedNamesToPlugins$jscomp$inline_263)
}
}
isOrderingDirty$jscomp$inline_264 && recomputePluginOrdering();
var emptyObject$1 = {},
var alwaysThrottleRetries = dynamicFlagsUntyped.alwaysThrottleRetries,
consoleManagedByDevToolsDuringStrictMode =
dynamicFlagsUntyped.consoleManagedByDevToolsDuringStrictMode,
enableAsyncActions = dynamicFlagsUntyped.enableAsyncActions,
enableEarlyReturnForPropDiffing =
dynamicFlagsUntyped.enableEarlyReturnForPropDiffing,
enableComponentStackLocations =
dynamicFlagsUntyped.enableComponentStackLocations,
enableDeferRootSchedulingToMicrotask =
dynamicFlagsUntyped.enableDeferRootSchedulingToMicrotask,
enableInfiniteRenderLoopDetection =
dynamicFlagsUntyped.enableInfiniteRenderLoopDetection,
enableRenderableContext = dynamicFlagsUntyped.enableRenderableContext,
enableUnifiedSyncLane = dynamicFlagsUntyped.enableUnifiedSyncLane,
passChildrenWhenCloningPersistedNodes =
dynamicFlagsUntyped.passChildrenWhenCloningPersistedNodes,
disableDefaultPropsExceptForClasses =
dynamicFlagsUntyped.disableDefaultPropsExceptForClasses,
emptyObject$1 = {},
removedKeys = null,
removedKeyCount = 0,
deepDifferOptions = { unsafelyIgnoreFunctions: !0 };
Expand Down Expand Up @@ -1268,23 +1286,7 @@ function dispatchEvent(target, topLevelType, nativeEvent) {
}
});
}
var alwaysThrottleRetries = dynamicFlagsUntyped.alwaysThrottleRetries,
consoleManagedByDevToolsDuringStrictMode =
dynamicFlagsUntyped.consoleManagedByDevToolsDuringStrictMode,
enableAsyncActions = dynamicFlagsUntyped.enableAsyncActions,
enableComponentStackLocations =
dynamicFlagsUntyped.enableComponentStackLocations,
enableDeferRootSchedulingToMicrotask =
dynamicFlagsUntyped.enableDeferRootSchedulingToMicrotask,
enableInfiniteRenderLoopDetection =
dynamicFlagsUntyped.enableInfiniteRenderLoopDetection,
enableRenderableContext = dynamicFlagsUntyped.enableRenderableContext,
enableUnifiedSyncLane = dynamicFlagsUntyped.enableUnifiedSyncLane,
passChildrenWhenCloningPersistedNodes =
dynamicFlagsUntyped.passChildrenWhenCloningPersistedNodes,
disableDefaultPropsExceptForClasses =
dynamicFlagsUntyped.disableDefaultPropsExceptForClasses,
scheduleCallback$3 = Scheduler.unstable_scheduleCallback,
var scheduleCallback$3 = Scheduler.unstable_scheduleCallback,
cancelCallback$1 = Scheduler.unstable_cancelCallback,
shouldYield = Scheduler.unstable_shouldYield,
requestPaint = Scheduler.unstable_requestPaint,
Expand Down Expand Up @@ -7554,12 +7556,15 @@ function completeWork(current, workInProgress, renderLanes) {
: createChildNodeSet()),
appendAllChildrenToContainer(newChildSet, workInProgress, !1, !1));
b: {
oldProps = diffProperties(
null,
oldProps,
newProps,
renderLanes.canonical.viewConfig.validAttributes
);
oldProps =
enableEarlyReturnForPropDiffing && oldProps === newProps
? null
: diffProperties(
null,
oldProps,
newProps,
renderLanes.canonical.viewConfig.validAttributes
);
renderLanes.canonical.currentProps = newProps;
newProps = renderLanes.node;
if (current)
Expand Down Expand Up @@ -11302,7 +11307,7 @@ var roots = new Map(),
devToolsConfig$jscomp$inline_1179 = {
findFiberByHostInstance: getInstanceFromNode,
bundleType: 0,
version: "19.0.0-canary-42633113",
version: "19.0.0-canary-ef6bcf29",
rendererPackageName: "react-native-renderer",
rendererConfig: {
getInspectorDataForInstance: getInspectorDataForInstance,
Expand Down Expand Up @@ -11358,7 +11363,7 @@ var roots = new Map(),
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "19.0.0-canary-42633113"
reconcilerVersion: "19.0.0-canary-ef6bcf29"
});
exports.createPortal = function (children, containerTag) {
return createPortal$1(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @noflow
* @nolint
* @preventMunge
* @generated SignedSource<<f5314f257c0eaf16ab8324449affda09>>
* @generated SignedSource<<cda44a9b6dde6c0bc692dd0a256b0422>>
*/

"use strict";
Expand Down Expand Up @@ -2688,6 +2688,8 @@ to return true:wantsResponderID| |
consoleManagedByDevToolsDuringStrictMode =
dynamicFlags.consoleManagedByDevToolsDuringStrictMode,
enableAsyncActions = dynamicFlags.enableAsyncActions,
enableEarlyReturnForPropDiffing =
dynamicFlags.enableEarlyReturnForPropDiffing,
enableComponentStackLocations =
dynamicFlags.enableComponentStackLocations,
enableDeferRootSchedulingToMicrotask =
Expand Down Expand Up @@ -3889,6 +3891,12 @@ to return true:wantsResponderID| |
);
}
function diff(prevProps, nextProps, validAttributes) {
if (enableEarlyReturnForPropDiffing) {
if (prevProps === nextProps) {
return null; // no change
}
}

return diffProperties(
null, // updatePayload
prevProps,
Expand Down Expand Up @@ -30742,7 +30750,7 @@ to return true:wantsResponderID| |
return root;
}

var ReactVersion = "19.0.0-canary-f19a567c";
var ReactVersion = "19.0.0-canary-ad24d706";

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

0 comments on commit 48cda4a

Please sign in to comment.