Fixed debug performance labels for new component types (#12609)
* Added new debug performance tests for AsyncMode, StrictMode, forwardRef, and context provider/consumer components. * Updated performance labels to exclude AsyncMode and StrictMode. * Added labels for forwardRef (and inner function) that mirror DevTools labels.
Brian Vaughn committed
Apr 12, 2018 at 09:39 UTC
5dfbfe9da740398c0a2cf4d897a0085000d06b7b
4 files changed
+120
packages/react-reconciler/src/ReactDebugFiberPerf.js
+2
@@ -21,6 +21,7 @@ import {
21
Fragment,
22
ContextProvider,
23
ContextConsumer,
24
+ Mode,
25
} from 'shared/ReactTypeOfWork';
26
27
type MeasurementPhase =
@@ -175,6 +176,7 @@ const shouldIgnoreFiber = (fiber: Fiber): boolean => {
176
case Fragment:
177
case ContextProvider:
178
case ContextConsumer:
179
+ case Mode:
180
return true;
181
default:
182
return false;
packages/react-reconciler/src/__tests__/ReactIncrementalPerf-test.internal.js
+58
@@ -161,6 +161,64 @@ describe('ReactDebugFiberPerf', () => {
161
expect(getFlameChart()).toMatchSnapshot();
162
});
163
164
+ it('properly displays the forwardRef component in measurements', () => {
165
+ const AnonymousForwardRef = React.forwardRef((props, ref) => (
166
+ <Child {...props} ref={ref} />
167
+ ));
168
+ const NamedForwardRef = React.forwardRef(function refForwarder(props, ref) {
169
+ return <Child {...props} ref={ref} />;
170
+ });
171
+ function notImportant(props, ref) {
172
+ return <Child {...props} ref={ref} />;
173
+ }
174
+ notImportant.displayName = 'OverriddenName';
175
+ const DisplayNamedForwardRef = React.forwardRef(notImportant);
176
+
177
+ ReactNoop.render(
178
+ <Parent>
179
+ <AnonymousForwardRef />
180
+ <NamedForwardRef />
181
+ <DisplayNamedForwardRef />
182
+ </Parent>,
183
+ );
184
+ addComment('Mount');
185
+ ReactNoop.flush();
186
+
187
+ expect(getFlameChart()).toMatchSnapshot();
188
+ });
189
+
190
+ it('does not include StrictMode or AsyncMode components in measurements', () => {
191
+ ReactNoop.render(
192
+ <React.StrictMode>
193
+ <Parent>
194
+ <React.unstable_AsyncMode>
195
+ <Child />
196
+ </React.unstable_AsyncMode>
197
+ </Parent>
198
+ </React.StrictMode>,
199
+ );
200
+ addComment('Mount');
201
+ ReactNoop.flush();
202
+
203
+ expect(getFlameChart()).toMatchSnapshot();
204
+ });
205
+
206
+ it('does not include context provider or consumer in measurements', () => {
207
+ const {Consumer, Provider} = React.createContext(true);
208
+
209
+ ReactNoop.render(
210
+ <Provider value={false}>
211
+ <Parent>
212
+ <Consumer>{value => <Child value={value} />}</Consumer>
213
+ </Parent>
214
+ </Provider>,
215
+ );
216
+ addComment('Mount');
217
+ ReactNoop.flush();
218
+
219
+ expect(getFlameChart()).toMatchSnapshot();
220
+ });
221
+
222
it('skips parents during setState', () => {
223
class A extends React.Component {
224
render() {
packages/react-reconciler/src/__tests__/__snapshots__/ReactIncrementalPerf-test.internal.js.snap
+50
@@ -91,6 +91,36 @@ exports[`ReactDebugFiberPerf deduplicates lifecycle names during commit to reduc
91
"
92
`;
93
94
+exports[`ReactDebugFiberPerf does not include StrictMode or AsyncMode components in measurements 1`] = `
95
+"⚛ (Waiting for async callback... will force flush in 5230 ms)
96
+
97
+// Mount
98
+⚛ (React Tree Reconciliation: Completed Root)
99
+ ⚛ Parent [mount]
100
+ ⚛ Child [mount]
101
+
102
+⚛ (Committing Changes)
103
+ ⚛ (Committing Snapshot Effects: 0 Total)
104
+ ⚛ (Committing Host Effects: 1 Total)
105
+ ⚛ (Calling Lifecycle Methods: 0 Total)
106
+"
107
+`;
108
+
109
+exports[`ReactDebugFiberPerf does not include context provider or consumer in measurements 1`] = `
110
+"⚛ (Waiting for async callback... will force flush in 5230 ms)
111
+
112
+// Mount
113
+⚛ (React Tree Reconciliation: Completed Root)
114
+ ⚛ Parent [mount]
115
+ ⚛ Child [mount]
116
+
117
+⚛ (Committing Changes)
118
+ ⚛ (Committing Snapshot Effects: 0 Total)
119
+ ⚛ (Committing Host Effects: 1 Total)
120
+ ⚛ (Calling Lifecycle Methods: 0 Total)
121
+"
122
+`;
123
+
124
exports[`ReactDebugFiberPerf does not schedule an extra callback if setState is called during a synchronous commit phase 1`] = `
125
"⚛ (React Tree Reconciliation: Completed Root)
126
⚛ Component [mount]
@@ -231,6 +261,26 @@ exports[`ReactDebugFiberPerf measures deprioritized work 1`] = `
261
"
262
`;
263
264
+exports[`ReactDebugFiberPerf properly displays the forwardRef component in measurements 1`] = `
265
+"⚛ (Waiting for async callback... will force flush in 5230 ms)
266
+
267
+// Mount
268
+⚛ (React Tree Reconciliation: Completed Root)
269
+ ⚛ Parent [mount]
270
+ ⚛ ForwardRef [mount]
271
+ ⚛ Child [mount]
272
+ ⚛ ForwardRef(refForwarder) [mount]
273
+ ⚛ Child [mount]
274
+ ⚛ ForwardRef(OverriddenName) [mount]
275
+ ⚛ Child [mount]
276
+
277
+⚛ (Committing Changes)
278
+ ⚛ (Committing Snapshot Effects: 0 Total)
279
+ ⚛ (Committing Host Effects: 1 Total)
280
+ ⚛ (Calling Lifecycle Methods: 0 Total)
281
+"
282
+`;
283
+
284
exports[`ReactDebugFiberPerf recovers from caught errors 1`] = `
285
"⚛ (Waiting for async callback... will force flush in 5230 ms)
286
packages/shared/getComponentName.js
+10
@@ -14,6 +14,7 @@ import {
14
REACT_FRAGMENT_TYPE,
15
REACT_RETURN_TYPE,
16
REACT_PORTAL_TYPE,
17
+ REACT_FORWARD_REF_TYPE,
18
} from 'shared/ReactSymbols';
19
20
function getComponentName(fiber: Fiber): string | null {
@@ -34,6 +35,15 @@ function getComponentName(fiber: Fiber): string | null {
35
case REACT_RETURN_TYPE:
36
return 'ReactReturn';
37
}
38
+ if (typeof type === 'object' && type !== null) {
39
+ switch (type.$$typeof) {
40
+ case REACT_FORWARD_REF_TYPE:
41
+ const functionName = type.render.displayName || type.render.name || '';
42
+ return functionName !== ''
43
+ ? `ForwardRef(${functionName})`
44
+ : 'ForwardRef';
45
+ }
46
+ }
47
return null;
48
}
49