Skip to content

Commit 75b58d2

Browse files
petehuntzpao
authored andcommitted
[perf] Wasted time metrics
This logs DOM ops for a given reconcile. Based on which components rendered and which ones *actually* caused DOM updates we can find opportunities to add shouldComponentUpdate() methods.
1 parent 94ef6c5 commit 75b58d2

File tree

1 file changed

+49
-1
lines changed

1 file changed

+49
-1
lines changed

src/test/ReactDefaultPerf.js

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,16 +85,24 @@ function getExclusiveSummary(measurements) {
8585
return arr;
8686
}
8787

88-
function getInclusiveSummary(measurements) {
88+
function getInclusiveSummary(measurements, onlyClean) {
8989
var inclusiveTimes = {};
9090
var displayName;
9191

9292
for (var i = 0; i < measurements.length; i++) {
9393
var measurement = measurements[i];
9494
var allIDs = merge(measurement.exclusive, measurement.inclusive);
95+
var cleanComponents;
9596

97+
if (onlyClean) {
98+
cleanComponents = getCleanComponents(measurement);
99+
}
96100

97101
for (var id in allIDs) {
102+
if (onlyClean && !cleanComponents[id]) {
103+
continue;
104+
}
105+
98106
displayName = measurement.displayNames[id];
99107

100108
// Inclusive time is not useful for many components without knowing where
@@ -129,6 +137,31 @@ function getInclusiveSummary(measurements) {
129137
return arr;
130138
}
131139

140+
function getCleanComponents(measurement) {
141+
// For a given reconcile, look at which components did not actually
142+
// render anything to the DOM and return a mapping of their ID to
143+
// the amount of time it took to render the entire subtree.
144+
var cleanComponents = {};
145+
var dirtyLeafIDs = Object.keys(measurement.writes);
146+
var allIDs = merge(measurement.exclusive, measurement.inclusive);
147+
148+
for (var id in allIDs) {
149+
var isDirty = false;
150+
// For each component that rendered, see if a component that triggerd
151+
// a DOM op is in its subtree.
152+
for (var i = 0; i < dirtyLeafIDs.length; i++) {
153+
if (dirtyLeafIDs[i].indexOf(id) === 0) {
154+
isDirty = true;
155+
break;
156+
}
157+
}
158+
if (!isDirty && measurement.counts[id] > 0) {
159+
cleanComponents[id] = true;
160+
}
161+
}
162+
return cleanComponents;
163+
}
164+
132165
var ReactDefaultPerf = {
133166
_allMeasurements: null, // last item in the list is the current one
134167
_injected: false,
@@ -181,6 +214,21 @@ var ReactDefaultPerf = {
181214
);
182215
},
183216

217+
printByWasted: function(measurements) {
218+
measurements = measurements || ReactDefaultPerf._allMeasurements;
219+
var summary = getInclusiveSummary(measurements, true);
220+
console.table(summary.map(function(item) {
221+
return {
222+
'Owner > component': item.componentName,
223+
'Wasted time': item.inclusiveTime.toFixed(2) + ' ms'
224+
};
225+
}));
226+
console.log(
227+
'Total DOM time:',
228+
getTotalDOMTime(measurements).toFixed(2) + ' ms'
229+
);
230+
},
231+
184232
_recordWrite: function(id, fnName, totalTime) {
185233
var writes =
186234
ReactDefaultPerf

0 commit comments

Comments
 (0)