mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Updates to perf
ReactDefaultPerf: * Show times as float instead of string. This means they're sortable. * Add count columns to all types and average to exclusive time. * Include mountComponent where updateComponent time is measured. * Increment count on _renderValidatedComponent instead of update. ReactDefaultPerfAnalysis: * Return counts with all summaries.
This commit is contained in:
committed by
Paul O’Shannessy
parent
5c953a7bdd
commit
acbba1ae67
@@ -26,8 +26,12 @@ var ReactPerf = require('ReactPerf');
|
||||
|
||||
var performanceNow = require('performanceNow');
|
||||
|
||||
function roundFloat(val) {
|
||||
return Math.floor(val * 100) / 100;
|
||||
}
|
||||
|
||||
var ReactDefaultPerf = {
|
||||
_allMeasurements: null, // last item in the list is the current one
|
||||
_allMeasurements: [], // last item in the list is the current one
|
||||
_injected: false,
|
||||
|
||||
start: function() {
|
||||
@@ -35,7 +39,7 @@ var ReactDefaultPerf = {
|
||||
ReactPerf.injection.injectMeasure(ReactDefaultPerf.measure);
|
||||
}
|
||||
|
||||
ReactDefaultPerf._allMeasurements = [];
|
||||
ReactDefaultPerf._allMeasurements.length = 0;
|
||||
ReactPerf.enableMeasure = true;
|
||||
},
|
||||
|
||||
@@ -53,8 +57,10 @@ var ReactDefaultPerf = {
|
||||
console.table(summary.map(function(item) {
|
||||
return {
|
||||
'Component class name': item.componentName,
|
||||
'Exclusive time': item.exclusiveTime.toFixed(2) + ' ms',
|
||||
'Inclusive time': item.inclusiveTime.toFixed(2) + ' ms'
|
||||
'Total inclusive time (ms)': roundFloat(item.inclusive),
|
||||
'Total exclusive time (ms)': roundFloat(item.exclusive),
|
||||
'Exclusive time per instance (ms)': roundFloat(item.exclusive / item.count),
|
||||
'Instances': item.count
|
||||
};
|
||||
}));
|
||||
console.log(
|
||||
@@ -69,7 +75,8 @@ var ReactDefaultPerf = {
|
||||
console.table(summary.map(function(item) {
|
||||
return {
|
||||
'Owner > component': item.componentName,
|
||||
'Inclusive time': item.inclusiveTime.toFixed(2) + ' ms'
|
||||
'Inclusive time (ms)': roundFloat(item.time),
|
||||
'Instances': item.count
|
||||
};
|
||||
}));
|
||||
console.log(
|
||||
@@ -87,7 +94,8 @@ var ReactDefaultPerf = {
|
||||
console.table(summary.map(function(item) {
|
||||
return {
|
||||
'Owner > component': item.componentName,
|
||||
'Wasted time': item.inclusiveTime.toFixed(2) + ' ms'
|
||||
'Wasted time (ms)': item.time,
|
||||
'Instances': item.count
|
||||
};
|
||||
}));
|
||||
console.log(
|
||||
@@ -195,27 +203,32 @@ var ReactDefaultPerf = {
|
||||
}
|
||||
return rv;
|
||||
} else if (moduleName === 'ReactCompositeComponent' && (
|
||||
fnName === 'mountComponent' ||
|
||||
fnName === 'updateComponent' || // TODO: receiveComponent()?
|
||||
fnName === '_renderValidatedComponent')) {
|
||||
var isInclusive = fnName === 'updateComponent';
|
||||
|
||||
var rootNodeID = fnName === 'mountComponent' ?
|
||||
args[0] :
|
||||
this._rootNodeID;
|
||||
var isRender = fnName === '_renderValidatedComponent';
|
||||
var entry = ReactDefaultPerf._allMeasurements[
|
||||
ReactDefaultPerf._allMeasurements.length - 1
|
||||
];
|
||||
if (isInclusive) {
|
||||
// Since both updateComponent() and _renderValidatedComponent() are
|
||||
// called for each render, only record the count for one of them.
|
||||
entry.counts[this._rootNodeID] = entry.counts[this._rootNodeID] || 0;
|
||||
entry.counts[this._rootNodeID] += 1;
|
||||
|
||||
if (isRender) {
|
||||
entry.counts[rootNodeID] = entry.counts[rootNodeID] || 0;
|
||||
entry.counts[rootNodeID] += 1;
|
||||
}
|
||||
|
||||
start = performanceNow();
|
||||
rv = func.apply(this, args);
|
||||
totalTime = performanceNow() - start;
|
||||
|
||||
var typeOfLog = isInclusive ? entry.inclusive : entry.exclusive;
|
||||
typeOfLog[this._rootNodeID] = typeOfLog[this._rootNodeID] || 0;
|
||||
typeOfLog[this._rootNodeID] += totalTime;
|
||||
var typeOfLog = isRender ? entry.exclusive : entry.inclusive;
|
||||
typeOfLog[rootNodeID] = typeOfLog[rootNodeID] || 0;
|
||||
typeOfLog[rootNodeID] += totalTime;
|
||||
|
||||
entry.displayNames[this._rootNodeID] = {
|
||||
entry.displayNames[rootNodeID] = {
|
||||
current: this.constructor.displayName,
|
||||
owner: this._owner ? this._owner.constructor.displayName : '<root>'
|
||||
};
|
||||
|
||||
@@ -77,8 +77,10 @@ function getExclusiveSummary(measurements) {
|
||||
displayName = measurement.displayNames[id].current;
|
||||
|
||||
candidates[displayName] = candidates[displayName] || {
|
||||
componentName: displayName,
|
||||
inclusive: 0,
|
||||
exclusive: 0
|
||||
exclusive: 0,
|
||||
count: 0
|
||||
};
|
||||
if (measurement.exclusive[id]) {
|
||||
candidates[displayName].exclusive += measurement.exclusive[id];
|
||||
@@ -86,32 +88,30 @@ function getExclusiveSummary(measurements) {
|
||||
if (measurement.inclusive[id]) {
|
||||
candidates[displayName].inclusive += measurement.inclusive[id];
|
||||
}
|
||||
if (measurement.counts[id]) {
|
||||
candidates[displayName].count += measurement.counts[id];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now make a sorted array with the results.
|
||||
var arr = [];
|
||||
for (displayName in candidates) {
|
||||
if (candidates[displayName].exclusiveTime < DONT_CARE_THRESHOLD) {
|
||||
continue;
|
||||
if (candidates[displayName].exclusive >= DONT_CARE_THRESHOLD) {
|
||||
arr.push(candidates[displayName]);
|
||||
}
|
||||
arr.push({
|
||||
componentName: displayName,
|
||||
exclusiveTime: candidates[displayName].exclusive,
|
||||
inclusiveTime: candidates[displayName].inclusive
|
||||
});
|
||||
}
|
||||
|
||||
arr.sort(function(a, b) {
|
||||
return b.exclusiveTime - a.exclusiveTime;
|
||||
return b.exclusive - a.exclusive;
|
||||
});
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
function getInclusiveSummary(measurements, onlyClean) {
|
||||
var inclusiveTimes = {};
|
||||
var displayName;
|
||||
var candidates = {};
|
||||
var inclusiveKey;
|
||||
|
||||
for (var i = 0; i < measurements.length; i++) {
|
||||
var measurement = measurements[i];
|
||||
@@ -127,35 +127,38 @@ function getInclusiveSummary(measurements, onlyClean) {
|
||||
continue;
|
||||
}
|
||||
|
||||
displayName = measurement.displayNames[id];
|
||||
var displayName = measurement.displayNames[id];
|
||||
|
||||
// Inclusive time is not useful for many components without knowing where
|
||||
// they are instantiated. So we aggregate inclusive time with both the
|
||||
// owner and current displayName as the key.
|
||||
var inclusiveKey = displayName.owner + ' > ' + displayName.current;
|
||||
inclusiveKey = displayName.owner + ' > ' + displayName.current;
|
||||
|
||||
inclusiveTimes[inclusiveKey] = inclusiveTimes[inclusiveKey] || 0;
|
||||
candidates[inclusiveKey] = candidates[inclusiveKey] || {
|
||||
componentName: inclusiveKey,
|
||||
time: 0,
|
||||
count: 0
|
||||
};
|
||||
|
||||
if (measurement.inclusive[id]) {
|
||||
inclusiveTimes[inclusiveKey] += measurement.inclusive[id];
|
||||
candidates[inclusiveKey].time += measurement.inclusive[id];
|
||||
}
|
||||
if (measurement.counts[id]) {
|
||||
candidates[inclusiveKey].count += measurement.counts[id];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now make a sorted array with the results.
|
||||
var arr = [];
|
||||
for (displayName in inclusiveTimes) {
|
||||
if (inclusiveTimes[displayName] < DONT_CARE_THRESHOLD) {
|
||||
continue;
|
||||
for (inclusiveKey in candidates) {
|
||||
if (candidates[inclusiveKey].time >= DONT_CARE_THRESHOLD) {
|
||||
arr.push(candidates[inclusiveKey]);
|
||||
}
|
||||
arr.push({
|
||||
componentName: displayName,
|
||||
inclusiveTime: inclusiveTimes[displayName]
|
||||
});
|
||||
}
|
||||
|
||||
arr.sort(function(a, b) {
|
||||
return b.inclusiveTime - a.inclusiveTime;
|
||||
return b.time - a.time;
|
||||
});
|
||||
|
||||
return arr;
|
||||
|
||||
Reference in New Issue
Block a user