diff --git a/packages/react-reconciler/src/ReactDebugFiberPerf.js b/packages/react-reconciler/src/ReactDebugFiberPerf.js index 1c84527e9ce77..0bd2dfb0ad4f9 100644 --- a/packages/react-reconciler/src/ReactDebugFiberPerf.js +++ b/packages/react-reconciler/src/ReactDebugFiberPerf.js @@ -21,6 +21,7 @@ import { Fragment, ContextProvider, ContextConsumer, + Mode, } from 'shared/ReactTypeOfWork'; type MeasurementPhase = @@ -175,6 +176,7 @@ const shouldIgnoreFiber = (fiber: Fiber): boolean => { case Fragment: case ContextProvider: case ContextConsumer: + case Mode: return true; default: return false; diff --git a/packages/react-reconciler/src/__tests__/ReactIncrementalPerf-test.internal.js b/packages/react-reconciler/src/__tests__/ReactIncrementalPerf-test.internal.js index 854a85efadc8c..d5dc2b6f6ab76 100644 --- a/packages/react-reconciler/src/__tests__/ReactIncrementalPerf-test.internal.js +++ b/packages/react-reconciler/src/__tests__/ReactIncrementalPerf-test.internal.js @@ -161,6 +161,64 @@ describe('ReactDebugFiberPerf', () => { expect(getFlameChart()).toMatchSnapshot(); }); + it('properly displays the forwardRef component in measurements', () => { + const AnonymousForwardRef = React.forwardRef((props, ref) => ( + + )); + const NamedForwardRef = React.forwardRef(function refForwarder(props, ref) { + return ; + }); + function notImportant(props, ref) { + return ; + } + notImportant.displayName = 'OverriddenName'; + const DisplayNamedForwardRef = React.forwardRef(notImportant); + + ReactNoop.render( + + + + + , + ); + addComment('Mount'); + ReactNoop.flush(); + + expect(getFlameChart()).toMatchSnapshot(); + }); + + it('does not include StrictMode or AsyncMode components in measurements', () => { + ReactNoop.render( + + + + + + + , + ); + addComment('Mount'); + ReactNoop.flush(); + + expect(getFlameChart()).toMatchSnapshot(); + }); + + it('does not include context provider or consumer in measurements', () => { + const {Consumer, Provider} = React.createContext(true); + + ReactNoop.render( + + + {value => } + + , + ); + addComment('Mount'); + ReactNoop.flush(); + + expect(getFlameChart()).toMatchSnapshot(); + }); + it('skips parents during setState', () => { class A extends React.Component { render() { diff --git a/packages/react-reconciler/src/__tests__/__snapshots__/ReactIncrementalPerf-test.internal.js.snap b/packages/react-reconciler/src/__tests__/__snapshots__/ReactIncrementalPerf-test.internal.js.snap index 48d0e6f4f67cd..40e37fe439489 100644 --- a/packages/react-reconciler/src/__tests__/__snapshots__/ReactIncrementalPerf-test.internal.js.snap +++ b/packages/react-reconciler/src/__tests__/__snapshots__/ReactIncrementalPerf-test.internal.js.snap @@ -91,6 +91,36 @@ exports[`ReactDebugFiberPerf deduplicates lifecycle names during commit to reduc " `; +exports[`ReactDebugFiberPerf does not include StrictMode or AsyncMode components in measurements 1`] = ` +"⚛ (Waiting for async callback... will force flush in 5230 ms) + +// Mount +⚛ (React Tree Reconciliation: Completed Root) + ⚛ Parent [mount] + ⚛ Child [mount] + +⚛ (Committing Changes) + ⚛ (Committing Snapshot Effects: 0 Total) + ⚛ (Committing Host Effects: 1 Total) + ⚛ (Calling Lifecycle Methods: 0 Total) +" +`; + +exports[`ReactDebugFiberPerf does not include context provider or consumer in measurements 1`] = ` +"⚛ (Waiting for async callback... will force flush in 5230 ms) + +// Mount +⚛ (React Tree Reconciliation: Completed Root) + ⚛ Parent [mount] + ⚛ Child [mount] + +⚛ (Committing Changes) + ⚛ (Committing Snapshot Effects: 0 Total) + ⚛ (Committing Host Effects: 1 Total) + ⚛ (Calling Lifecycle Methods: 0 Total) +" +`; + exports[`ReactDebugFiberPerf does not schedule an extra callback if setState is called during a synchronous commit phase 1`] = ` "⚛ (React Tree Reconciliation: Completed Root) ⚛ Component [mount] @@ -231,6 +261,26 @@ exports[`ReactDebugFiberPerf measures deprioritized work 1`] = ` " `; +exports[`ReactDebugFiberPerf properly displays the forwardRef component in measurements 1`] = ` +"⚛ (Waiting for async callback... will force flush in 5230 ms) + +// Mount +⚛ (React Tree Reconciliation: Completed Root) + ⚛ Parent [mount] + ⚛ ForwardRef [mount] + ⚛ Child [mount] + ⚛ ForwardRef(refForwarder) [mount] + ⚛ Child [mount] + ⚛ ForwardRef(OverriddenName) [mount] + ⚛ Child [mount] + +⚛ (Committing Changes) + ⚛ (Committing Snapshot Effects: 0 Total) + ⚛ (Committing Host Effects: 1 Total) + ⚛ (Calling Lifecycle Methods: 0 Total) +" +`; + exports[`ReactDebugFiberPerf recovers from caught errors 1`] = ` "⚛ (Waiting for async callback... will force flush in 5230 ms) diff --git a/packages/shared/getComponentName.js b/packages/shared/getComponentName.js index e00bd89725162..23e10d1a73a97 100644 --- a/packages/shared/getComponentName.js +++ b/packages/shared/getComponentName.js @@ -14,6 +14,7 @@ import { REACT_FRAGMENT_TYPE, REACT_RETURN_TYPE, REACT_PORTAL_TYPE, + REACT_FORWARD_REF_TYPE, } from 'shared/ReactSymbols'; function getComponentName(fiber: Fiber): string | null { @@ -34,6 +35,15 @@ function getComponentName(fiber: Fiber): string | null { case REACT_RETURN_TYPE: return 'ReactReturn'; } + if (typeof type === 'object' && type !== null) { + switch (type.$$typeof) { + case REACT_FORWARD_REF_TYPE: + const functionName = type.render.displayName || type.render.name || ''; + return functionName !== '' + ? `ForwardRef(${functionName})` + : 'ForwardRef'; + } + } return null; }