@samitouri / QOS-React / commits / a37012a6b5

Add Bailout effectTag for React DevTools (#9887)

* Add Bailout effectTag for React DevTools * Instead of tracking bailout, track performed work

Dan Abramov committed Jun 8, 2017 at 21:23 UTC a37012a6b5fb5a1c0c19c962737189aeaebe3684
3 files changed +33 -14
src/renderers/shared/fiber/ReactFiberBeginWork.js
+13 -1
@@ -50,7 +50,13 @@ var {
50 Fragment,
51 } = ReactTypeOfWork;
52 var {NoWork, OffscreenPriority} = require('ReactPriorityLevel');
53 -var {Placement, ContentReset, Err, Ref} = require('ReactTypeOfSideEffect');
53 +var {
54 + PerformedWork,
55 + Placement,
56 + ContentReset,
57 + Err,
58 + Ref,
59 +} = require('ReactTypeOfSideEffect');
60 var ReactFiberClassComponent = require('ReactFiberClassComponent');
61 var {ReactCurrentOwner} = require('ReactGlobalSharedState');
62 var invariant = require('fbjs/lib/invariant');
@@ -249,6 +255,8 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
255 } else {
256 nextChildren = fn(nextProps, context);
257 }
258 + // React DevTools reads this flag.
259 + workInProgress.effectTag |= PerformedWork;
260 reconcileChildren(current, workInProgress, nextChildren);
261 memoizeProps(workInProgress, nextProps);
262 return workInProgress.child;
@@ -315,6 +323,8 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
323 } else {
324 nextChildren = instance.render();
325 }
326 + // React DevTools reads this flag.
327 + workInProgress.effectTag |= PerformedWork;
328 reconcileChildren(current, workInProgress, nextChildren);
329 // Memoize props and state using the values we just used to render.
330 // TODO: Restructure so we never read values from the instance.
@@ -548,6 +558,8 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
558 } else {
559 value = fn(props, context);
560 }
561 + // React DevTools reads this flag.
562 + workInProgress.effectTag |= PerformedWork;
563
564 if (
565 typeof value === 'object' &&
src/renderers/shared/fiber/ReactFiberScheduler.js
+8 -4
@@ -64,7 +64,7 @@ var {
64 var {AsyncUpdates} = require('ReactTypeOfInternalContext');
65
66 var {
67 - NoEffect,
67 + PerformedWork,
68 Placement,
69 Update,
70 PlacementAndUpdate,
@@ -335,7 +335,8 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
335 // updates, and deletions. To avoid needing to add a case for every
336 // possible bitmap value, we remove the secondary effects from the
337 // effect tag and switch on that value.
338 - let primaryEffectTag = effectTag & ~(Callback | Err | ContentReset | Ref);
338 + let primaryEffectTag =
339 + effectTag & ~(Callback | Err | ContentReset | Ref | PerformedWork);
340 switch (primaryEffectTag) {
341 case Placement: {
342 commitPlacement(nextEffect);
@@ -445,7 +446,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
446 priorityContext = TaskPriority;
447
448 let firstEffect;
448 - if (finishedWork.effectTag !== NoEffect) {
449 + if (finishedWork.effectTag > PerformedWork) {
450 // A fiber's effect list consists only of its children, not itself. So if
451 // the root has an effect, we need to add it to the end of the list. The
452 // resulting list is the set that would belong to the root's parent, if
@@ -641,7 +642,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
642 // to schedule our own side-effect on our own list because if end up
643 // reusing children we'll schedule this effect onto itself since we're
644 // at the end.
644 - if (workInProgress.effectTag !== NoEffect) {
645 + const effectTag = workInProgress.effectTag;
646 + // Skip both NoWork and PerformedWork tags when creating the effect list.
647 + // PerformedWork effect is read by React DevTools but shouldn't be committed.
648 + if (effectTag > PerformedWork) {
649 if (returnFiber.lastEffect !== null) {
650 returnFiber.lastEffect.nextEffect = workInProgress;
651 } else {
src/renderers/shared/fiber/ReactTypeOfSideEffect.js
+12 -9
@@ -15,13 +15,16 @@
15 export type TypeOfSideEffect = number;
16
17 module.exports = {
18 - NoEffect: 0, // 0b0000000
19 - Placement: 1, // 0b0000001
20 - Update: 2, // 0b0000010
21 - PlacementAndUpdate: 3, // 0b0000011
22 - Deletion: 4, // 0b0000100
23 - ContentReset: 8, // 0b0001000
24 - Callback: 16, // 0b0010000
25 - Err: 32, // 0b0100000
26 - Ref: 64, // 0b1000000
18 + // Don't change these two values:
19 + NoEffect: 0, // 0b00000000
20 + PerformedWork: 1, // 0b00000001
21 + // You can change the rest (and add more).
22 + Placement: 2, // 0b00000010
23 + Update: 4, // 0b00000100
24 + PlacementAndUpdate: 6, // 0b00000110
25 + Deletion: 8, // 0b00001000
26 + ContentReset: 16, // 0b00010000
27 + Callback: 32, // 0b00100000
28 + Err: 64, // 0b01000000
29 + Ref: 128, // 0b10000000
30 };