Skip to content

Commit

Permalink
Add DebugTraceMode to limit logging by subtree
Browse files Browse the repository at this point in the history
  • Loading branch information
Brian Vaughn committed Apr 7, 2020
1 parent ad55d2d commit 99714f2
Show file tree
Hide file tree
Showing 15 changed files with 155 additions and 46 deletions.
3 changes: 3 additions & 0 deletions packages/react-devtools-shared/src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
ForwardRef,
Fragment,
Lazy,
DebugTraceMode,
Memo,
Portal,
Profiler,
Expand Down Expand Up @@ -432,6 +433,8 @@ export function getDisplayNameForReactElement(
return 'Fragment';
case Lazy:
return 'Lazy';
case DebugTraceMode:
return 'DebugTraceMode';
case Memo:
return 'Memo';
case Portal:
Expand Down
5 changes: 5 additions & 0 deletions packages/react-is/src/ReactIs.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
REACT_FORWARD_REF_TYPE,
REACT_FRAGMENT_TYPE,
REACT_LAZY_TYPE,
REACT_DEBUG_TRACE_MODE_TYPE,
REACT_MEMO_TYPE,
REACT_PORTAL_TYPE,
REACT_PROFILER_TYPE,
Expand Down Expand Up @@ -65,6 +66,7 @@ export const Element = REACT_ELEMENT_TYPE;
export const ForwardRef = REACT_FORWARD_REF_TYPE;
export const Fragment = REACT_FRAGMENT_TYPE;
export const Lazy = REACT_LAZY_TYPE;
export const DebugTraceMode = REACT_DEBUG_TRACE_MODE_TYPE;
export const Memo = REACT_MEMO_TYPE;
export const Portal = REACT_PORTAL_TYPE;
export const Profiler = REACT_PROFILER_TYPE;
Expand Down Expand Up @@ -125,6 +127,9 @@ export function isFragment(object: any) {
export function isLazy(object: any) {
return typeOf(object) === REACT_LAZY_TYPE;
}
export function isDebugTraceMode(object: any) {
return typeOf(object) === REACT_DEBUG_TRACE_MODE_TYPE;
}
export function isMemo(object: any) {
return typeOf(object) === REACT_MEMO_TYPE;
}
Expand Down
6 changes: 6 additions & 0 deletions packages/react-reconciler/src/ReactFiber.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,14 @@ import {
NoMode,
ConcurrentMode,
ProfileMode,
DebugTraceMode,
StrictMode,
BlockingMode,
} from './ReactTypeOfMode';
import {
REACT_FORWARD_REF_TYPE,
REACT_FRAGMENT_TYPE,
REACT_DEBUG_TRACE_MODE_TYPE,
REACT_STRICT_MODE_TYPE,
REACT_PROFILER_TYPE,
REACT_PROVIDER_TYPE,
Expand Down Expand Up @@ -635,6 +637,10 @@ export function createFiberFromTypeAndProps(
expirationTime,
key,
);
case REACT_DEBUG_TRACE_MODE_TYPE:
fiberTag = Mode;
mode |= DebugTraceMode;
break;
case REACT_STRICT_MODE_TYPE:
fiberTag = Mode;
mode |= StrictMode;
Expand Down
38 changes: 22 additions & 16 deletions packages/react-reconciler/src/ReactFiberClassComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import invariant from 'shared/invariant';
import {REACT_CONTEXT_TYPE, REACT_PROVIDER_TYPE} from 'shared/ReactSymbols';

import {resolveDefaultProps} from './ReactFiberLazyComponent';
import {StrictMode} from './ReactTypeOfMode';
import {DebugTraceMode, StrictMode} from './ReactTypeOfMode';

import {
enqueueUpdate,
Expand Down Expand Up @@ -207,11 +207,13 @@ const classComponentUpdater = {

if (__DEV__) {
if (enableDebugTracing) {
const label = priorityLevelToLabel(
((update.priority: any): ReactPriorityLevel),
);
const name = getComponentName(fiber.type) || 'Unknown';
logStateUpdateScheduled(name, label, payload);
if (fiber.mode & DebugTraceMode) {
const label = priorityLevelToLabel(
((update.priority: any): ReactPriorityLevel),
);
const name = getComponentName(fiber.type) || 'Unknown';
logStateUpdateScheduled(name, label, payload);
}
}
}
},
Expand Down Expand Up @@ -241,11 +243,13 @@ const classComponentUpdater = {

if (__DEV__) {
if (enableDebugTracing) {
const label = priorityLevelToLabel(
((update.priority: any): ReactPriorityLevel),
);
const name = getComponentName(fiber.type) || 'Unknown';
logStateUpdateScheduled(name, label, payload);
if (fiber.mode & DebugTraceMode) {
const label = priorityLevelToLabel(
((update.priority: any): ReactPriorityLevel),
);
const name = getComponentName(fiber.type) || 'Unknown';
logStateUpdateScheduled(name, label, payload);
}
}
}
},
Expand Down Expand Up @@ -274,11 +278,13 @@ const classComponentUpdater = {

if (__DEV__) {
if (enableDebugTracing) {
const label = priorityLevelToLabel(
((update.priority: any): ReactPriorityLevel),
);
const name = getComponentName(fiber.type) || 'Unknown';
logForceUpdateScheduled(name, label);
if (fiber.mode & DebugTraceMode) {
const label = priorityLevelToLabel(
((update.priority: any): ReactPriorityLevel),
);
const name = getComponentName(fiber.type) || 'Unknown';
logForceUpdateScheduled(name, label);
}
}
}
},
Expand Down
18 changes: 10 additions & 8 deletions packages/react-reconciler/src/ReactFiberHooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import ReactSharedInternals from 'shared/ReactSharedInternals';
import {enableDebugTracing, enableUseEventAPI} from 'shared/ReactFeatureFlags';

import {markRootExpiredAtTime} from './ReactFiberRoot';
import {NoMode, BlockingMode} from './ReactTypeOfMode';
import {NoMode, BlockingMode, DebugTraceMode} from './ReactTypeOfMode';
import {
inferPriorityFromExpirationTime,
NoWork,
Expand Down Expand Up @@ -1787,13 +1787,15 @@ function dispatchAction<S, A>(

if (__DEV__) {
if (enableDebugTracing) {
const priorityLevel = inferPriorityFromExpirationTime(
currentTime,
expirationTime,
);
const label = priorityLevelToLabel(priorityLevel);
const name = getComponentName(fiber.type) || 'Unknown';
logStateUpdateScheduled(name, label, action);
if (fiber.mode & DebugTraceMode) {
const priorityLevel = inferPriorityFromExpirationTime(
currentTime,
expirationTime,
);
const label = priorityLevelToLabel(priorityLevel);
const name = getComponentName(fiber.type) || 'Unknown';
logStateUpdateScheduled(name, label, action);
}
}
}
}
Expand Down
8 changes: 5 additions & 3 deletions packages/react-reconciler/src/ReactFiberThrow.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import {
ShouldCapture,
LifecycleEffectMask,
} from './ReactSideEffectTags';
import {NoMode, BlockingMode} from './ReactTypeOfMode';
import {NoMode, BlockingMode, DebugTraceMode} from './ReactTypeOfMode';
import {shouldCaptureSuspense} from './ReactFiberSuspenseComponent';
import {enableDebugTracing} from 'shared/ReactFeatureFlags';
import {createCapturedValue} from './ReactCapturedValue';
Expand Down Expand Up @@ -197,8 +197,10 @@ function throwException(

if (__DEV__) {
if (enableDebugTracing) {
const name = getComponentName(sourceFiber.type) || 'Unknown';
logComponentSuspended(name, wakeable);
if (sourceFiber.mode & DebugTraceMode) {
const name = getComponentName(sourceFiber.type) || 'Unknown';
logComponentSuspended(name, wakeable);
}
}
}

Expand Down
11 changes: 6 additions & 5 deletions packages/react-reconciler/src/ReactTypeOfMode.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@

export type TypeOfMode = number;

export const NoMode = 0b0000;
export const StrictMode = 0b0001;
export const NoMode = 0b00000;
export const StrictMode = 0b00001;
export const DebugTraceMode = 0b10000;
// TODO: Remove BlockingMode and ConcurrentMode by reading from the root
// tag instead
export const BlockingMode = 0b0010;
export const ConcurrentMode = 0b0100;
export const ProfileMode = 0b1000;
export const BlockingMode = 0b00010;
export const ConcurrentMode = 0b00100;
export const ProfileMode = 0b01000;
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,11 @@ describe('DebugTracing', () => {
});
} else {
it('should not log anything for sync render without suspends or state updates', () => {
ReactTestRenderer.create(<div />);
ReactTestRenderer.create(
<React.DebugTraceMode>
<div />
</React.DebugTraceMode>,
);

expect(logs).toEqual(['log: ⚛️ render scheduled (priority: immediate)']);
});
Expand All @@ -74,9 +78,11 @@ describe('DebugTracing', () => {
}

ReactTestRenderer.create(
<React.Suspense fallback={null}>
<Example />
</React.Suspense>,
<React.DebugTraceMode>
<React.Suspense fallback={null}>
<Example />
</React.Suspense>
</React.DebugTraceMode>,
);

expect(logs).toEqual([
Expand All @@ -94,9 +100,11 @@ describe('DebugTracing', () => {
}

ReactTestRenderer.create(
<React.Suspense fallback={null}>
<Example />
</React.Suspense>,
<React.DebugTraceMode>
<React.Suspense fallback={null}>
<Example />
</React.Suspense>
</React.DebugTraceMode>,
{unstable_isConcurrent: true},
);

Expand Down Expand Up @@ -124,7 +132,12 @@ describe('DebugTracing', () => {
}
}

ReactTestRenderer.create(<Example />, {unstable_isConcurrent: true});
ReactTestRenderer.create(
<React.DebugTraceMode>
<Example />
</React.DebugTraceMode>,
{unstable_isConcurrent: true},
);

expect(logs).toEqual(['log: ⚛️ render scheduled (priority: normal)']);

Expand Down Expand Up @@ -152,7 +165,12 @@ describe('DebugTracing', () => {
}
}

ReactTestRenderer.create(<Example />, {unstable_isConcurrent: true});
ReactTestRenderer.create(
<React.DebugTraceMode>
<Example />
</React.DebugTraceMode>,
{unstable_isConcurrent: true},
);

expect(logs).toEqual(['log: ⚛️ render scheduled (priority: normal)']);

Expand All @@ -179,7 +197,12 @@ describe('DebugTracing', () => {
return didMount;
}

ReactTestRenderer.create(<Example />, {unstable_isConcurrent: true});
ReactTestRenderer.create(
<React.DebugTraceMode>
<Example />
</React.DebugTraceMode>,
{unstable_isConcurrent: true},
);

expect(logs).toEqual(['log: ⚛️ render scheduled (priority: normal)']);

Expand All @@ -206,7 +229,12 @@ describe('DebugTracing', () => {
}

ReactTestRenderer.act(() => {
ReactTestRenderer.create(<Example />, {unstable_isConcurrent: true});
ReactTestRenderer.create(
<React.DebugTraceMode>
<Example />
</React.DebugTraceMode>,
{unstable_isConcurrent: true},
);
});
expect(logs).toEqual([
'log: ⚛️ render scheduled (priority: normal)',
Expand All @@ -226,7 +254,12 @@ describe('DebugTracing', () => {
}

ReactTestRenderer.act(() => {
ReactTestRenderer.create(<Example />, {unstable_isConcurrent: true});
ReactTestRenderer.create(
<React.DebugTraceMode>
<Example />
</React.DebugTraceMode>,
{unstable_isConcurrent: true},
);
});
expect(logs).toEqual([
'log: ⚛️ render scheduled (priority: normal)',
Expand All @@ -243,7 +276,12 @@ describe('DebugTracing', () => {
return null;
}

ReactTestRenderer.create(<Example />, {unstable_isConcurrent: true});
ReactTestRenderer.create(
<React.DebugTraceMode>
<Example />
</React.DebugTraceMode>,
{unstable_isConcurrent: true},
);

expect(logs).toEqual(['log: ⚛️ render scheduled (priority: normal)']);

Expand All @@ -254,9 +292,42 @@ describe('DebugTracing', () => {
expect(logs).toEqual([
'group: ⚛️ render (priority: normal)',
'log: Hello from user code',
'log: Hello from user code', // debugRenderPhaseSideEffectsForStrictMode
'log: Hello from user code', // d'ebugRenderPhaseSideEffectsForStrictMode
'groupEnd: ⚛️ render (priority: normal)',
]);
});

it('should not log anything outside of a DebugTraceMode subtree', () => {
function ExampleThatCascades() {
const [didMount, setDidMount] = React.useState(false);
React.useLayoutEffect(() => {
setDidMount(true);
}, []);
return didMount;
}

const fakeSuspensPromise = new Promise(() => {});
function ExampleThatSuspends() {
throw fakeSuspensPromise;
}

function Example() {
return null;
}

ReactTestRenderer.create(
<React.Fragment>
<ExampleThatCascades />
<React.Suspense fallback={null}>
<ExampleThatSuspends />
</React.Suspense>
<React.DebugTraceMode>
<Example />
</React.DebugTraceMode>
</React.Fragment>,
);

expect(logs).toEqual(['log: ⚛️ render scheduled (priority: immediate)']);
});
}
});
2 changes: 2 additions & 0 deletions packages/react/index.classic.fb.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,7 @@ export {
// enableScopeAPI
unstable_createScope,
unstable_useOpaqueIdentifier,
// enableDebugTracing
DebugTraceMode,
} from './src/React';
export {jsx, jsxs, jsxDEV} from './src/jsx/ReactJSX';
2 changes: 2 additions & 0 deletions packages/react/index.experimental.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,6 @@ export {
// enableBlocksAPI
block,
unstable_useOpaqueIdentifier,
// enableDebugTracing
DebugTraceMode,
} from './src/React';
1 change: 1 addition & 0 deletions packages/react/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export {
createMutableSource,
Fragment,
Profiler,
DebugTraceMode,
StrictMode,
Suspense,
createElement,
Expand Down
Loading

0 comments on commit 99714f2

Please sign in to comment.