Skip to content

Commit c7d55de

Browse files
committed
Make class prop resolution faster (#28766)
`delete` causes an object (in V8, and maybe other engines) to deopt to a dictionary instead of a class. Instead of `assign` + `delete`, manually iterate over all the properties, like the JSX runtime does. To avoid copying the object twice I moved the `ref` prop removal to come before handling default props. If we already cloned the props to remove `ref`, then we can skip cloning again to handle default props. DiffTrain build for [bfd8da8](bfd8da8)
1 parent 1d8cde0 commit c7d55de

23 files changed

+1715
-1623
lines changed

compiled/facebook-www/REVISION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
cbb6f2b5461cdce282c7e47b9c68a0897d393383
1+
bfd8da807c75a2d123627415f9eaf2d36ac3ed6a

compiled/facebook-www/ReactART-dev.classic.js

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ if (__DEV__) {
6666
return self;
6767
}
6868

69-
var ReactVersion = "19.0.0-www-classic-da2c086d";
69+
var ReactVersion = "19.0.0-www-classic-fcdce517";
7070

7171
var LegacyRoot = 0;
7272
var ConcurrentRoot = 1;
@@ -14287,7 +14287,20 @@ if (__DEV__) {
1428714287
// remove this extra check.
1428814288
alreadyResolvedDefaultProps
1428914289
) {
14290-
var newProps = baseProps; // Resolve default props. Taken from old JSX runtime, where this used to live.
14290+
var newProps = baseProps;
14291+
14292+
if (enableRefAsProp) {
14293+
// Remove ref from the props object, if it exists.
14294+
if ("ref" in baseProps) {
14295+
newProps = {};
14296+
14297+
for (var propName in baseProps) {
14298+
if (propName !== "ref") {
14299+
newProps[propName] = baseProps[propName];
14300+
}
14301+
}
14302+
}
14303+
} // Resolve default props.
1429114304

1429214305
var defaultProps = Component.defaultProps;
1429314306

@@ -14296,26 +14309,19 @@ if (__DEV__) {
1429614309
// default props here in the reconciler, rather than in the JSX runtime.
1429714310
(disableDefaultPropsExceptForClasses || !alreadyResolvedDefaultProps)
1429814311
) {
14299-
newProps = assign({}, newProps, baseProps);
14312+
// We may have already copied the props object above to remove ref. If so,
14313+
// we can modify that. Otherwise, copy the props object with Object.assign.
14314+
if (newProps === baseProps) {
14315+
newProps = assign({}, newProps, baseProps);
14316+
} // Taken from old JSX runtime, where this used to live.
1430014317

14301-
for (var propName in defaultProps) {
14302-
if (newProps[propName] === undefined) {
14303-
newProps[propName] = defaultProps[propName];
14318+
for (var _propName in defaultProps) {
14319+
if (newProps[_propName] === undefined) {
14320+
newProps[_propName] = defaultProps[_propName];
1430414321
}
1430514322
}
1430614323
}
1430714324

14308-
if (enableRefAsProp) {
14309-
// Remove ref from the props object, if it exists.
14310-
if ("ref" in newProps) {
14311-
if (newProps === baseProps) {
14312-
newProps = assign({}, newProps);
14313-
}
14314-
14315-
delete newProps.ref;
14316-
}
14317-
}
14318-
1431914325
return newProps;
1432014326
}
1432114327

compiled/facebook-www/ReactART-dev.modern.js

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ if (__DEV__) {
6666
return self;
6767
}
6868

69-
var ReactVersion = "19.0.0-www-modern-a4bdb396";
69+
var ReactVersion = "19.0.0-www-modern-f3bc72db";
7070

7171
var LegacyRoot = 0;
7272
var ConcurrentRoot = 1;
@@ -13997,7 +13997,20 @@ if (__DEV__) {
1399713997
// remove this extra check.
1399813998
alreadyResolvedDefaultProps
1399913999
) {
14000-
var newProps = baseProps; // Resolve default props. Taken from old JSX runtime, where this used to live.
14000+
var newProps = baseProps;
14001+
14002+
if (enableRefAsProp) {
14003+
// Remove ref from the props object, if it exists.
14004+
if ("ref" in baseProps) {
14005+
newProps = {};
14006+
14007+
for (var propName in baseProps) {
14008+
if (propName !== "ref") {
14009+
newProps[propName] = baseProps[propName];
14010+
}
14011+
}
14012+
}
14013+
} // Resolve default props.
1400114014

1400214015
var defaultProps = Component.defaultProps;
1400314016

@@ -14006,26 +14019,19 @@ if (__DEV__) {
1400614019
// default props here in the reconciler, rather than in the JSX runtime.
1400714020
(disableDefaultPropsExceptForClasses || !alreadyResolvedDefaultProps)
1400814021
) {
14009-
newProps = assign({}, newProps, baseProps);
14022+
// We may have already copied the props object above to remove ref. If so,
14023+
// we can modify that. Otherwise, copy the props object with Object.assign.
14024+
if (newProps === baseProps) {
14025+
newProps = assign({}, newProps, baseProps);
14026+
} // Taken from old JSX runtime, where this used to live.
1401014027

14011-
for (var propName in defaultProps) {
14012-
if (newProps[propName] === undefined) {
14013-
newProps[propName] = defaultProps[propName];
14028+
for (var _propName in defaultProps) {
14029+
if (newProps[_propName] === undefined) {
14030+
newProps[_propName] = defaultProps[_propName];
1401414031
}
1401514032
}
1401614033
}
1401714034

14018-
if (enableRefAsProp) {
14019-
// Remove ref from the props object, if it exists.
14020-
if ("ref" in newProps) {
14021-
if (newProps === baseProps) {
14022-
newProps = assign({}, newProps);
14023-
}
14024-
14025-
delete newProps.ref;
14026-
}
14027-
}
14028-
1402914035
return newProps;
1403014036
}
1403114037

0 commit comments

Comments
 (0)