Skip to content

Commit 760262e

Browse files
authored
Add Profiler component for collecting new render timing info (#12745)
Add a new component type, Profiler, that can be used to collect new render time metrics. Since this is a new, experimental API, it will be exported as React.unstable_Profiler initially. Most of the functionality for this component has been added behind a feature flag, enableProfileModeMetrics. When the feature flag is disabled, the component will just render its children with no additional behavior. When the flag is enabled, React will also collect timing information and pass it to the onRender function (as described below).
1 parent 7127e87 commit 760262e

File tree

3 files changed

+45
-6
lines changed

3 files changed

+45
-6
lines changed

src/ReactTestRenderer.js

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import {
2727
ContextProvider,
2828
Mode,
2929
ForwardRef,
30+
Profiler,
3031
} from 'shared/ReactTypeOfWork';
3132
import invariant from 'fbjs/lib/invariant';
3233

@@ -119,7 +120,7 @@ function removeChild(
119120
}
120121

121122
// Current virtual time
122-
let currentTime: number = 0;
123+
let nowImplementation = () => 0;
123124
let scheduledCallback: ((deadline: Deadline) => mixed) | null = null;
124125
let yieldedValues: Array<mixed> | null = null;
125126

@@ -221,9 +222,9 @@ const TestRenderer = ReactFiberReconciler({
221222

222223
getPublicInstance,
223224

224-
now(): number {
225-
return currentTime;
226-
},
225+
// This approach enables `now` to be mocked by tests,
226+
// Even after the reconciler has initialized and read host config values.
227+
now: () => nowImplementation(),
227228

228229
mutation: {
229230
commitUpdate(
@@ -383,6 +384,7 @@ function toTree(node: ?Fiber) {
383384
case ContextProvider:
384385
case ContextConsumer:
385386
case Mode:
387+
case Profiler:
386388
case ForwardRef:
387389
return childrenToTree(node.child);
388390
default:
@@ -486,6 +488,7 @@ class ReactTestInstance {
486488
case ContextProvider:
487489
case ContextConsumer:
488490
case Mode:
491+
case Profiler:
489492
descend = true;
490493
break;
491494
default:
@@ -737,7 +740,11 @@ const ReactTestRendererFiber = {
737740
}
738741
return TestRenderer.getPublicRootInstance(root);
739742
},
740-
unstable_flushSync: TestRenderer.flushSync,
743+
unstable_flushSync(fn: Function) {
744+
yieldedValues = [];
745+
TestRenderer.flushSync(fn);
746+
return yieldedValues;
747+
},
741748
};
742749

743750
Object.defineProperty(
@@ -761,6 +768,10 @@ const ReactTestRendererFiber = {
761768
/* eslint-disable camelcase */
762769
unstable_batchedUpdates: batchedUpdates,
763770
/* eslint-enable camelcase */
771+
772+
unstable_setNowImplementation(implementation: () => number): void {
773+
nowImplementation = implementation;
774+
},
764775
};
765776

766777
export default ReactTestRendererFiber;

src/__tests__/ReactShallowRenderer-test.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,32 @@ describe('ReactShallowRenderer', () => {
230230
]);
231231
});
232232

233+
it('should handle Profiler', () => {
234+
class SomeComponent extends React.Component {
235+
render() {
236+
return (
237+
<React.unstable_Profiler id="test" onRender={jest.fn()}>
238+
<div>
239+
<span className="child1" />
240+
<span className="child2" />
241+
</div>
242+
</React.unstable_Profiler>
243+
);
244+
}
245+
}
246+
247+
const shallowRenderer = createRenderer();
248+
const result = shallowRenderer.render(<SomeComponent />);
249+
250+
expect(result.type).toBe(React.unstable_Profiler);
251+
expect(result.props.children).toEqual(
252+
<div>
253+
<span className="child1" />
254+
<span className="child2" />
255+
</div>,
256+
);
257+
});
258+
233259
it('should enable shouldComponentUpdate to prevent a re-render', () => {
234260
let renderCounter = 0;
235261
class SimpleComponent extends React.Component {

src/__tests__/ReactTestRendererTraversal-test.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ describe('ReactTestRendererTraversal', () => {
3737
<View void="void" />
3838
<View void="void" />
3939
</ExampleNull>
40-
<ExampleForwardRef qux="qux" />
40+
<React.unstable_Profiler id="test" onRender={() => {}}>
41+
<ExampleForwardRef qux="qux" />
42+
</React.unstable_Profiler>
4143
</View>
4244
</View>
4345
);

0 commit comments

Comments
 (0)