Prevent performance regression in DEV due to warning arguments (#7461)
* Prevent internal performance regression This only affects Facebook website, not open source version of React. On the Facebook website, we don't have a transform for warnings and invariants. Therefore, expensive arguments will be calculated even if the warning doesn't fire. This fixes a few cases where that calculation might be more expensive than usually. In my testing, this brings down average row click time in Power Editor from ~300ms to ~220ms in __DEV__ (vs ~40ms in prod). * Put warning() that shows up in profile behind condition
Dan Abramov committed
Aug 10, 2016 at 19:52 UTC
178cb7d3392505cd393b68e4e061c6ef860344a1
7 files changed
+46
-35
src/isomorphic/classic/element/ReactElementValidator.js
+9
-7
@@ -188,13 +188,15 @@ var ReactElementValidator = {
188
(type !== null && typeof type === 'object');
189
// We warn in this case but don't throw. We expect the element creation to
190
// succeed and there will likely be errors in render.
191
- warning(
192
- validType,
193
- 'React.createElement: type should not be null, undefined, boolean, or ' +
194
- 'number. It should be a string (for DOM elements) or a ReactClass ' +
195
- '(for composite components).%s',
196
- getDeclarationErrorAddendum()
197
- );
191
+ if (!validType) {
192
+ warning(
193
+ false,
194
+ 'React.createElement: type should not be null, undefined, boolean, or ' +
195
+ 'number. It should be a string (for DOM elements) or a ReactClass ' +
196
+ '(for composite components).%s',
197
+ getDeclarationErrorAddendum()
198
+ );
199
+ }
200
201
var element = ReactElement.createElement.apply(this, arguments);
202
src/renderers/dom/client/wrappers/ReactDOMSelect.js
+5
-4
@@ -71,17 +71,18 @@ function checkSelectPropTypes(inst, props) {
71
if (props[propName] == null) {
72
continue;
73
}
74
- if (props.multiple) {
74
+ var isArray = Array.isArray(props[propName]);
75
+ if (props.multiple && !isArray) {
76
warning(
76
- Array.isArray(props[propName]),
77
+ false,
78
'The `%s` prop supplied to <select> must be an array if ' +
79
'`multiple` is true.%s',
80
propName,
81
getDeclarationErrorAddendum(owner)
82
);
82
- } else {
83
+ } else if (!props.multiple && isArray) {
84
warning(
84
- !Array.isArray(props[propName]),
85
+ false,
86
'The `%s` prop supplied to <select> must be a scalar ' +
87
'value if `multiple` is false.%s',
88
propName,
src/renderers/dom/shared/hooks/ReactDOMUnknownPropertyHook.js
+2
-2
@@ -69,7 +69,7 @@ if (__DEV__) {
69
70
if (standardName != null) {
71
warning(
72
- standardName == null,
72
+ false,
73
'Unknown DOM property %s. Did you mean %s?%s',
74
name,
75
standardName,
@@ -78,7 +78,7 @@ if (__DEV__) {
78
return true;
79
} else if (registrationName != null) {
80
warning(
81
- registrationName == null,
81
+ false,
82
'Unknown event handler property %s. Did you mean `%s`?%s',
83
name,
84
registrationName,
src/renderers/shared/ReactDebugTool.js
+3
-1
@@ -104,7 +104,9 @@ function resetMeasurements() {
104
}
105
106
function checkDebugID(debugID) {
107
- warning(debugID, 'ReactDebugTool: debugID may not be empty.');
107
+ if (!debugID) {
108
+ warning(false, 'ReactDebugTool: debugID may not be empty.');
109
+ }
110
}
111
112
function beginLifeCycleTimer(debugID, timerType) {
src/renderers/shared/hooks/ReactChildrenMutationWarningHook.js
+7
-5
@@ -37,11 +37,13 @@ function handleElement(debugID, element) {
37
isMutated = true;
38
}
39
}
40
- warning(
41
- Array.isArray(element._shadowChildren) && !isMutated,
42
- 'Component\'s children should not be mutated.%s',
43
- ReactComponentTreeHook.getStackAddendumByID(debugID),
44
- );
40
+ if (!Array.isArray(element._shadowChildren) || isMutated) {
41
+ warning(
42
+ false,
43
+ 'Component\'s children should not be mutated.%s',
44
+ ReactComponentTreeHook.getStackAddendumByID(debugID),
45
+ );
46
+ }
47
}
48
49
var ReactChildrenMutationWarningHook = {
src/renderers/shared/stack/reconciler/ReactChildReconciler.js
+10
-8
@@ -41,14 +41,16 @@ function instantiateChild(childInstances, child, name, selfDebugID) {
41
if (!ReactComponentTreeHook) {
42
ReactComponentTreeHook = require('ReactComponentTreeHook');
43
}
44
- warning(
45
- keyUnique,
46
- 'flattenChildren(...): Encountered two children with the same key, ' +
47
- '`%s`. Child keys must be unique; when two children share a key, only ' +
48
- 'the first child will be used.%s',
49
- KeyEscapeUtils.unescape(name),
50
- ReactComponentTreeHook.getStackAddendumByID(selfDebugID)
51
- );
44
+ if (!keyUnique) {
45
+ warning(
46
+ false,
47
+ 'flattenChildren(...): Encountered two children with the same key, ' +
48
+ '`%s`. Child keys must be unique; when two children share a key, only ' +
49
+ 'the first child will be used.%s',
50
+ KeyEscapeUtils.unescape(name),
51
+ ReactComponentTreeHook.getStackAddendumByID(selfDebugID)
52
+ );
53
+ }
54
}
55
if (child != null && keyUnique) {
56
childInstances[name] = instantiateReactComponent(child, true);
src/shared/utils/flattenChildren.js
+10
-8
@@ -51,14 +51,16 @@ function flattenSingleChildIntoContext(
51
if (!ReactComponentTreeHook) {
52
ReactComponentTreeHook = require('ReactComponentTreeHook');
53
}
54
- warning(
55
- keyUnique,
56
- 'flattenChildren(...): Encountered two children with the same key, ' +
57
- '`%s`. Child keys must be unique; when two children share a key, only ' +
58
- 'the first child will be used.%s',
59
- KeyEscapeUtils.unescape(name),
60
- ReactComponentTreeHook.getStackAddendumByID(selfDebugID)
61
- );
54
+ if (!keyUnique) {
55
+ warning(
56
+ false,
57
+ 'flattenChildren(...): Encountered two children with the same key, ' +
58
+ '`%s`. Child keys must be unique; when two children share a key, only ' +
59
+ 'the first child will be used.%s',
60
+ KeyEscapeUtils.unescape(name),
61
+ ReactComponentTreeHook.getStackAddendumByID(selfDebugID)
62
+ );
63
+ }
64
}
65
if (keyUnique && child != null) {
66
result[name] = child;