Skip to content

Commit

Permalink
Fix componentWillUnmount() not counted by ReactPerf (facebook#6858)
Browse files Browse the repository at this point in the history
* Fix componentWillUnmount() not counted by ReactPerf

* Test that functional component render() time shows up in ReactPerf

* Test for setState() code path updates being included

(cherry picked from commit 9ba5668)
  • Loading branch information
gaearon authored and zpao committed Jun 8, 2016
1 parent f7c9d93 commit 60897bb
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 2 deletions.
6 changes: 6 additions & 0 deletions src/renderers/dom/client/ReactMount.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,13 @@ function batchedMountComponentIntoNode(
* @see {ReactMount.unmountComponentAtNode}
*/
function unmountComponentFromNode(instance, container, safely) {
if (__DEV__) {
ReactInstrumentation.debugTool.onBeginFlush();
}
ReactReconciler.unmountComponent(instance, safely);
if (__DEV__) {
ReactInstrumentation.debugTool.onEndFlush();
}

if (container.nodeType === DOC_NODE_TYPE) {
container = container.documentElement;
Expand Down
77 changes: 75 additions & 2 deletions src/renderers/shared/__tests__/ReactPerf-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ describe('ReactPerf', function() {
var ReactDOM;
var ReactPerf;
var ReactTestUtils;
var emptyFunction;

var App;
var Box;
var Div;
var LifeCycle;

beforeEach(function() {
var now = 0;
Expand All @@ -36,6 +38,7 @@ describe('ReactPerf', function() {
ReactDOM = require('ReactDOM');
ReactPerf = require('ReactPerf');
ReactTestUtils = require('ReactTestUtils');
emptyFunction = require('emptyFunction');

App = React.createClass({
render: function() {
Expand All @@ -55,6 +58,17 @@ describe('ReactPerf', function() {
return <div {...this.props} />;
},
});

LifeCycle = React.createClass({
shouldComponentUpdate: emptyFunction.thatReturnsTrue,
componentWillMount: emptyFunction,
componentDidMount: emptyFunction,
componentWillReceiveProps: emptyFunction,
componentWillUpdate: emptyFunction,
componentDidUpdate: emptyFunction,
componentWillUnmount: emptyFunction,
render: emptyFunction.thatReturnsNull,
});
});

afterEach(function() {
Expand Down Expand Up @@ -215,7 +229,7 @@ describe('ReactPerf', function() {
});
});

it('should not count replacing null with a native as waste', function() {
it('should not count replacing null with a host as waste', function() {
var element = null;
function Foo() {
return element;
Expand All @@ -228,7 +242,7 @@ describe('ReactPerf', function() {
});
});

it('should not count replacing a native with null as waste', function() {
it('should not count replacing a host with null as waste', function() {
var element = <div />;
function Foo() {
return element;
Expand Down Expand Up @@ -256,6 +270,65 @@ describe('ReactPerf', function() {
}]);
});

it('should include lifecycle methods in measurements', function() {
var container = document.createElement('div');
var measurements = measure(() => {
var instance = ReactDOM.render(<LifeCycle />, container);
ReactDOM.render(<LifeCycle />, container);
instance.setState({});
ReactDOM.unmountComponentAtNode(container);
});
expect(ReactPerf.getExclusive(measurements)).toEqual([{
key: 'LifeCycle',
instanceCount: 1,
totalDuration: 14,
counts: {
ctor: 1,
shouldComponentUpdate: 2,
componentWillMount: 1,
componentDidMount: 1,
componentWillReceiveProps: 1,
componentWillUpdate: 2,
componentDidUpdate: 2,
componentWillUnmount: 1,
render: 3,
},
durations: {
ctor: 1,
shouldComponentUpdate: 2,
componentWillMount: 1,
componentDidMount: 1,
componentWillReceiveProps: 1,
componentWillUpdate: 2,
componentDidUpdate: 2,
componentWillUnmount: 1,
render: 3,
},
}]);
});

it('should include render time of functional components', function() {
function Foo() {
return null;
}

var container = document.createElement('div');
var measurements = measure(() => {
ReactDOM.render(<Foo />, container);
});
expect(ReactPerf.getExclusive(measurements)).toEqual([{
key: 'Foo',
instanceCount: 1,
totalDuration: 1,
counts: {
render: 1,
},
durations: {
render: 1,
},
}]);
});

it('warns once when using getMeasurementsSummaryMap', function() {
var measurements = measure(() => {});
spyOn(console, 'error');
Expand Down

0 comments on commit 60897bb

Please sign in to comment.