Ignore DOM writes outside the batch in ReactPerf
ReactDOMInput and a few other classes handle change event by scheduling updateWrapper() in an asap(). It gets executed after the batch, which confuses ReactPerf that expects all DOM writes to happen during a batch. Since this implementation of ReactPerf relying on the stack is going away, let's plug the hole temporarily by ignoring DOM writes that occur during postponed updateWrapper(). In any case, they have no relation to actual calculations of wasted renders, as they don't occur due to updateComponent(), but rather due to onChange() special DOM behavior. This fixes #5548
Dan Abramov committed
Apr 14, 2016 at 20:48 UTC
3b2860222051cd3978529a89e4eb3193e23c6c26
2 files changed
+15
-2
src/test/ReactDefaultPerfAnalysis.js
+3
-2
@@ -175,12 +175,13 @@ function getUnchangedComponents(measurement) {
175
// the amount of time it took to render the entire subtree.
176
var cleanComponents = {};
177
var writes = measurement.writes;
178
+ var hierarchy = measurement.hierarchy;
179
var dirtyComposites = {};
180
Object.keys(writes).forEach(function(id) {
181
writes[id].forEach(function(write) {
182
// Root mounting (innerHTML set) is recorded with an ID of ''
182
- if (id !== '') {
183
- measurement.hierarchy[id].forEach((c) => dirtyComposites[c] = true);
183
+ if (id !== '' && hierarchy.hasOwnProperty(id)) {
184
+ hierarchy[id].forEach((c) => dirtyComposites[c] = true);
185
}
186
});
187
});
src/test/__tests__/ReactDefaultPerf-test.js
+12
@@ -239,6 +239,18 @@ describe('ReactDefaultPerf', function() {
239
expect(summary).toEqual([]);
240
});
241
242
+ it('should not fail on input change events', function() {
243
+ var container = document.createElement('div');
244
+ var onChange = () => {};
245
+ var input = ReactDOM.render(
246
+ <input checked={true} onChange={onChange} />,
247
+ container
248
+ );
249
+ expectNoWaste(() => {
250
+ ReactTestUtils.Simulate.change(input);
251
+ });
252
+ });
253
+
254
it('should print a table after calling printOperations', function() {
255
var container = document.createElement('div');
256
var measurements = measure(() => {