DevTools shows which fibers scheduled the current update (#21171)

This commit is contained in:
Brian Vaughn
2021-04-09 10:35:06 -04:00
committed by GitHub
parent dc108b0f55
commit bdc23c3dba
17 changed files with 639 additions and 56 deletions
@@ -13,18 +13,21 @@ Array [
"displayName": "Grandparent",
"hocDisplayNames": null,
"id": 2,
"key": null,
"type": 5,
},
Object {
"displayName": "Parent",
"hocDisplayNames": null,
"id": 3,
"key": null,
"type": 5,
},
Object {
"displayName": "Child",
"hocDisplayNames": null,
"id": 4,
"key": null,
"type": 5,
},
]
@@ -44,18 +47,21 @@ Array [
"displayName": "Grandparent",
"hocDisplayNames": null,
"id": 2,
"key": null,
"type": 5,
},
Object {
"displayName": "Parent",
"hocDisplayNames": null,
"id": 3,
"key": null,
"type": 5,
},
Object {
"displayName": "Child",
"hocDisplayNames": null,
"id": 4,
"key": null,
"type": 5,
},
]
@@ -67,12 +73,14 @@ Array [
"displayName": "Grandparent",
"hocDisplayNames": null,
"id": 2,
"key": null,
"type": 5,
},
Object {
"displayName": "Parent",
"hocDisplayNames": null,
"id": 3,
"key": null,
"type": 5,
},
]
@@ -84,6 +92,7 @@ Array [
"displayName": "Grandparent",
"hocDisplayNames": null,
"id": 2,
"key": null,
"type": 5,
},
Object {
@@ -92,6 +101,7 @@ Array [
"Memo",
],
"id": 3,
"key": null,
"type": 8,
},
Object {
@@ -100,6 +110,7 @@ Array [
"ForwardRef",
],
"id": 4,
"key": null,
"type": 6,
},
]
@@ -116,6 +127,7 @@ Array [
"displayName": "Grandparent",
"hocDisplayNames": null,
"id": 2,
"key": null,
"type": 5,
},
]
@@ -43,6 +43,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Normal",
"timestamp": 16,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
}
`;
@@ -82,6 +91,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Normal",
"timestamp": 15,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
}
`;
@@ -110,6 +128,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Immediate",
"timestamp": 18,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
}
`;
@@ -165,6 +192,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Normal",
"timestamp": 12,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
}
`;
@@ -222,6 +258,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Immediate",
"timestamp": 25,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
}
`;
@@ -261,6 +306,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Immediate",
"timestamp": 35,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
}
`;
@@ -291,6 +345,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Immediate",
"timestamp": 45,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
}
`;
@@ -392,6 +455,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Normal",
"timestamp": 12,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
},
Object {
"changeDescriptions": Array [
@@ -488,6 +560,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Immediate",
"timestamp": 25,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
},
Object {
"changeDescriptions": Array [
@@ -548,6 +629,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Immediate",
"timestamp": 35,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
},
Object {
"changeDescriptions": Array [
@@ -590,6 +680,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Immediate",
"timestamp": 45,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
},
],
"displayName": "Parent",
@@ -736,7 +835,7 @@ Object {
"snapshots": Array [],
},
],
"version": 4,
"version": 5,
}
`;
@@ -855,6 +954,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Normal",
"timestamp": 11,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
},
Object {
"changeDescriptions": Array [
@@ -933,6 +1041,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Immediate",
"timestamp": 22,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
},
Object {
"changeDescriptions": Array [
@@ -1029,6 +1146,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Immediate",
"timestamp": 35,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
},
],
"displayName": "Parent",
@@ -1170,7 +1296,7 @@ Object {
"snapshots": Array [],
},
],
"version": 4,
"version": 5,
}
`;
@@ -1230,6 +1356,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Immediate",
"timestamp": 13,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
},
Object {
"changeDescriptions": Map {
@@ -1266,6 +1401,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Immediate",
"timestamp": 34,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
},
Object {
"changeDescriptions": Map {
@@ -1293,6 +1437,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Immediate",
"timestamp": 44,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
},
],
"displayName": "Parent",
@@ -1470,6 +1623,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Normal",
"timestamp": 24,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 11,
"key": null,
"type": 11,
},
],
},
],
"displayName": "Parent",
@@ -1554,6 +1716,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Normal",
"timestamp": 34,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 6,
"key": null,
"type": 11,
},
],
},
],
"displayName": "Parent",
@@ -1723,6 +1894,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Immediate",
"timestamp": 13,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
},
Object {
"changeDescriptions": Array [
@@ -1783,6 +1963,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Immediate",
"timestamp": 34,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
},
Object {
"changeDescriptions": Array [
@@ -1825,6 +2014,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Immediate",
"timestamp": 44,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
},
],
"displayName": "Parent",
@@ -2062,6 +2260,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Normal",
"timestamp": 24,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 11,
"key": null,
"type": 11,
},
],
},
],
"displayName": "Parent",
@@ -2143,6 +2350,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Normal",
"timestamp": 34,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 6,
"key": null,
"type": 11,
},
],
},
],
"displayName": "Parent",
@@ -2235,7 +2451,7 @@ Object {
],
},
],
"version": 4,
"version": 5,
}
`;
@@ -2258,6 +2474,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Normal",
"timestamp": 0,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
},
],
"displayName": "Suspense",
@@ -2327,6 +2552,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Normal",
"timestamp": 0,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
}
`;
@@ -2359,6 +2593,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Immediate",
"timestamp": 0,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
}
`;
@@ -2385,6 +2628,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Immediate",
"timestamp": 0,
"updaters": Array [
Object {
"displayName": "Component",
"hocDisplayNames": null,
"id": 3,
"key": null,
"type": 5,
},
],
}
`;
@@ -2411,6 +2663,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Immediate",
"timestamp": 0,
"updaters": Array [
Object {
"displayName": "Component",
"hocDisplayNames": null,
"id": 3,
"key": null,
"type": 5,
},
],
}
`;
@@ -2441,6 +2702,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Immediate",
"timestamp": 0,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
}
`;
@@ -2496,6 +2766,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Normal",
"timestamp": 0,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
},
Object {
"changeDescriptions": Array [
@@ -2546,6 +2825,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Immediate",
"timestamp": 0,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
},
Object {
"changeDescriptions": Array [
@@ -2578,6 +2866,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Immediate",
"timestamp": 0,
"updaters": Array [
Object {
"displayName": "Component",
"hocDisplayNames": null,
"id": 3,
"key": null,
"type": 5,
},
],
},
Object {
"changeDescriptions": Array [
@@ -2610,6 +2907,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Immediate",
"timestamp": 0,
"updaters": Array [
Object {
"displayName": "Component",
"hocDisplayNames": null,
"id": 3,
"key": null,
"type": 5,
},
],
},
Object {
"changeDescriptions": Array [
@@ -2658,6 +2964,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Immediate",
"timestamp": 0,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
},
],
"displayName": "Component",
@@ -2747,7 +3062,7 @@ Object {
"snapshots": Array [],
},
],
"version": 4,
"version": 5,
}
`;
@@ -2814,6 +3129,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Normal",
"timestamp": 0,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
}
`;
@@ -2886,6 +3210,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Immediate",
"timestamp": 0,
"updaters": Array [
Object {
"displayName": "LegacyContextProvider",
"hocDisplayNames": null,
"id": 2,
"key": null,
"type": 1,
},
],
}
`;
@@ -2954,6 +3287,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Immediate",
"timestamp": 0,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
}
`;
@@ -3023,6 +3365,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Immediate",
"timestamp": 0,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
}
`;
@@ -3091,6 +3442,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Immediate",
"timestamp": 0,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
}
`;
@@ -3218,6 +3578,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Normal",
"timestamp": 0,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
},
Object {
"changeDescriptions": Array [
@@ -3338,6 +3707,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Immediate",
"timestamp": 0,
"updaters": Array [
Object {
"displayName": "LegacyContextProvider",
"hocDisplayNames": null,
"id": 2,
"key": null,
"type": 1,
},
],
},
Object {
"changeDescriptions": Array [
@@ -3460,6 +3838,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Immediate",
"timestamp": 0,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
},
Object {
"changeDescriptions": Array [
@@ -3583,6 +3970,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Immediate",
"timestamp": 0,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
},
Object {
"changeDescriptions": Array [
@@ -3705,6 +4101,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Immediate",
"timestamp": 0,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
},
],
"displayName": "LegacyContextProvider",
@@ -3917,7 +4322,7 @@ Object {
"snapshots": Array [],
},
],
"version": 4,
"version": 5,
}
`;
@@ -4020,6 +4425,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Normal",
"timestamp": 11,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
},
Object {
"changeDescriptions": Array [
@@ -4100,6 +4514,15 @@ Object {
"passiveEffectDuration": null,
"priorityLevel": "Immediate",
"timestamp": 22,
"updaters": Array [
Object {
"displayName": "Anonymous",
"hocDisplayNames": null,
"id": 1,
"key": null,
"type": 11,
},
],
},
],
"displayName": "Parent",
@@ -4237,6 +4660,6 @@ Object {
"snapshots": Array [],
},
],
"version": 4,
"version": 5,
}
`;
@@ -22,6 +22,6 @@ describe('profiling utils', () => {
dataForRoots: [],
}: any),
),
).toThrow('Unsupported profiler export version "0"');
).toThrow('Unsupported profile export version');
});
});
@@ -51,7 +51,7 @@ import type {
ComponentFilter,
ElementType,
} from 'react-devtools-shared/src/types';
import type {Owner, InspectedElement} from '../types';
import type {InspectedElement, SerializedElement} from '../types';
export type InternalInstance = Object;
type LegacyRenderer = Object;
@@ -767,6 +767,7 @@ export function attach(
owners.push({
displayName: getData(owner).displayName || 'Unknown',
id: getID(owner),
key: element.key,
type: getElementType(owner),
});
if (owner._currentElement) {
@@ -1047,7 +1048,7 @@ export function attach(
// Not implemented.
}
function getOwnersList(id: number): Array<Owner> | null {
function getOwnersList(id: number): Array<SerializedElement> | null {
// Not implemented.
return null;
}
+28 -21
View File
@@ -81,6 +81,8 @@ import {
} from './ReactSymbols';
import {format} from './utils';
import {enableProfilerChangedHookIndices} from 'react-devtools-feature-flags';
import is from 'shared/objectIs';
import isArray from 'shared/isArray';
import type {Fiber} from 'react-reconciler/src/ReactInternalTypes';
import type {
@@ -91,13 +93,13 @@ import type {
InspectedElementPayload,
InstanceAndStyle,
NativeType,
Owner,
PathFrame,
PathMatch,
ProfilingDataBackend,
ProfilingDataForRootBackend,
ReactRenderer,
RendererInterface,
SerializedElement,
WorkTagMap,
} from './types';
import type {Interaction} from 'react-devtools-shared/src/devtools/views/Profiler/types';
@@ -105,8 +107,6 @@ import type {
ComponentFilter,
ElementType,
} from 'react-devtools-shared/src/types';
import is from 'shared/objectIs';
import isArray from 'shared/isArray';
type getDisplayNameForFiberType = (fiber: Fiber) => string | null;
type getTypeSymbolType = (type: any) => Symbol | number;
@@ -2172,6 +2172,7 @@ export function attach(
),
maxActualDuration: 0,
priorityLevel: null,
updaters: getUpdatersList(root),
effectDuration: null,
passiveEffectDuration: null,
};
@@ -2184,6 +2185,12 @@ export function attach(
}
}
function getUpdatersList(root): Array<SerializedElement> | null {
return root.memoizedUpdaters != null
? Array.from(root.memoizedUpdaters).map(fiberToSerializedElement)
: null;
}
function handleCommitFiberUnmount(fiber) {
// This is not recursive.
// We can't traverse fibers after unmounting so instead
@@ -2241,6 +2248,8 @@ export function attach(
priorityLevel:
priorityLevel == null ? null : formatPriorityLevel(priorityLevel),
updaters: getUpdatersList(root),
// Initialize to null; if new enough React version is running,
// these values will be read during separate handlePostCommitFiberRoot() call.
effectDuration: null,
@@ -2637,7 +2646,16 @@ export function attach(
}
}
function getOwnersList(id: number): Array<Owner> | null {
function fiberToSerializedElement(fiber: Fiber): SerializedElement {
return {
displayName: getDisplayNameForFiber(fiber) || 'Anonymous',
id: getFiberID(getPrimaryFiber(fiber)),
key: fiber.key,
type: getElementTypeForFiber(fiber),
};
}
function getOwnersList(id: number): Array<SerializedElement> | null {
const fiber = findCurrentFiberUsingSlowPathById(id);
if (fiber == null) {
return null;
@@ -2645,22 +2663,12 @@ export function attach(
const {_debugOwner} = fiber;
const owners = [
{
displayName: getDisplayNameForFiber(fiber) || 'Anonymous',
id,
type: getElementTypeForFiber(fiber),
},
];
const owners: Array<SerializedElement> = [fiberToSerializedElement(fiber)];
if (_debugOwner) {
let owner = _debugOwner;
while (owner !== null) {
owners.unshift({
displayName: getDisplayNameForFiber(owner) || 'Anonymous',
id: getFiberID(getPrimaryFiber(owner)),
type: getElementTypeForFiber(owner),
});
owners.unshift(fiberToSerializedElement(owner));
owner = owner._debugOwner || null;
}
}
@@ -2791,11 +2799,7 @@ export function attach(
owners = [];
let owner = _debugOwner;
while (owner !== null) {
owners.push({
displayName: getDisplayNameForFiber(owner) || 'Anonymous',
id: getFiberID(getPrimaryFiber(owner)),
type: getElementTypeForFiber(owner),
});
owners.push(fiberToSerializedElement(owner));
owner = owner._debugOwner || null;
}
}
@@ -3380,6 +3384,7 @@ export function attach(
maxActualDuration: number,
passiveEffectDuration: number | null,
priorityLevel: string | null,
updaters: Array<SerializedElement> | null,
|};
type CommitProfilingMetadataMap = Map<number, Array<CommitProfilingData>>;
@@ -3438,6 +3443,7 @@ export function attach(
passiveEffectDuration,
priorityLevel,
commitTime,
updaters,
} = commitProfilingData;
const interactionIDs: Array<number> = [];
@@ -3478,6 +3484,7 @@ export function attach(
passiveEffectDuration,
priorityLevel,
timestamp: commitTime,
updaters,
});
});
+6 -4
View File
@@ -168,6 +168,7 @@ export type CommitDataBackend = {|
passiveEffectDuration: number | null,
priorityLevel: string | null,
timestamp: number,
updaters: Array<SerializedElement> | null,
|};
export type ProfilingDataForRootBackend = {|
@@ -199,15 +200,16 @@ export type PathMatch = {|
isFullMatch: boolean,
|};
export type Owner = {|
export type SerializedElement = {|
displayName: string | null,
id: number,
key: number | string | null,
type: ElementType,
|};
export type OwnersList = {|
id: number,
owners: Array<Owner> | null,
owners: Array<SerializedElement> | null,
|};
export type InspectedElement = {|
@@ -244,7 +246,7 @@ export type InspectedElement = {|
warnings: Array<[string, number]>,
// List of owners
owners: Array<Owner> | null,
owners: Array<SerializedElement> | null,
// Location of component in source code.
source: Source | null,
@@ -322,7 +324,7 @@ export type RendererInterface = {
getDisplayNameForFiberID: GetDisplayNameForFiberID,
getInstanceAndStyle(id: number): InstanceAndStyle,
getProfilingData(): ProfilingDataBackend,
getOwnersList: (id: number) => Array<Owner> | null,
getOwnersList: (id: number) => Array<SerializedElement> | null,
getPathForElement: (id: number) => Array<PathFrame> | null,
handleCommitFiberRoot: (fiber: Object, commitPriority?: number) => void,
handleCommitFiberUnmount: (fiber: Object) => void,
+1 -1
View File
@@ -41,7 +41,7 @@ export const LOCAL_STORAGE_SHOW_INLINE_WARNINGS_AND_ERRORS_KEY =
export const LOCAL_STORAGE_TRACE_UPDATES_ENABLED_KEY =
'React::DevTools::traceUpdatesEnabled';
export const PROFILER_EXPORT_VERSION = 4;
export const PROFILER_EXPORT_VERSION = 5;
export const CHANGE_LOG_URL =
'https://github.com/facebook/react/blob/master/packages/react-devtools/CHANGELOG.md';
@@ -35,7 +35,7 @@ import {
import styles from './InspectedElementView.css';
import type {ContextMenuContextType} from '../context';
import type {Element, InspectedElement, Owner} from './types';
import type {Element, InspectedElement, SerializedElement} from './types';
import type {ElementType} from 'react-devtools-shared/src/types';
export type CopyPath = (path: Array<string | number>) => void;
@@ -127,7 +127,7 @@ export default function InspectedElementView({
<div className={styles.Owners}>
<div className={styles.OwnersHeader}>rendered by</div>
{showOwnersList &&
((owners: any): Array<Owner>).map(owner => (
((owners: any): Array<SerializedElement>).map(owner => (
<OwnerView
key={owner.id}
displayName={owner.displayName || 'Anonymous'}
@@ -17,23 +17,27 @@ import {separateDisplayNameAndHOCs} from 'react-devtools-shared/src/utils';
import type {OwnersList} from 'react-devtools-shared/src/backend/types';
import type {
Element,
Owner,
SerializedElement,
} from 'react-devtools-shared/src/devtools/views/Components/types';
import type {Resource, Thenable} from '../../cache';
type Context = (id: number) => Array<Owner> | null;
type Context = (id: number) => Array<SerializedElement> | null;
const OwnersListContext = createContext<Context>(((null: any): Context));
OwnersListContext.displayName = 'OwnersListContext';
type ResolveFn = (ownersList: Array<Owner> | null) => void;
type ResolveFn = (ownersList: Array<SerializedElement> | null) => void;
type InProgressRequest = {|
promise: Thenable<Array<Owner>>,
promise: Thenable<Array<SerializedElement>>,
resolveFn: ResolveFn,
|};
const inProgressRequests: WeakMap<Element, InProgressRequest> = new WeakMap();
const resource: Resource<Element, Element, Array<Owner>> = createResource(
const resource: Resource<
Element,
Element,
Array<SerializedElement>,
> = createResource(
(element: Element) => {
const request = inProgressRequests.get(element);
if (request != null) {
@@ -27,16 +27,16 @@ import {TreeDispatcherContext, TreeStateContext} from './TreeContext';
import {useIsOverflowing} from '../hooks';
import {StoreContext} from '../context';
import type {Owner} from './types';
import type {SerializedElement} from './types';
import styles from './OwnersStack.css';
type SelectOwner = (owner: Owner | null) => void;
type SelectOwner = (owner: SerializedElement | null) => void;
type ACTION_UPDATE_OWNER_ID = {|
type: 'UPDATE_OWNER_ID',
ownerID: number | null,
owners: Array<Owner>,
owners: Array<SerializedElement>,
|};
type ACTION_UPDATE_SELECTED_INDEX = {|
type: 'UPDATE_SELECTED_INDEX',
@@ -47,7 +47,7 @@ type Action = ACTION_UPDATE_OWNER_ID | ACTION_UPDATE_SELECTED_INDEX;
type State = {|
ownerID: number | null,
owners: Array<Owner>,
owners: Array<SerializedElement>,
selectedIndex: number,
|};
@@ -104,7 +104,7 @@ export default function OwnerStack() {
const {owners, selectedIndex} = state;
const selectOwner = useCallback<SelectOwner>(
(owner: Owner | null) => {
(owner: SerializedElement | null) => {
if (owner !== null) {
const index = owners.indexOf(owner);
dispatch({
@@ -197,7 +197,7 @@ export default function OwnerStack() {
}
type ElementsDropdownProps = {
owners: Array<Owner>,
owners: Array<SerializedElement>,
selectedIndex: number,
selectOwner: SelectOwner,
...
@@ -245,7 +245,7 @@ function ElementsDropdown({
type ElementViewProps = {
isSelected: boolean,
owner: Owner,
owner: SerializedElement,
selectOwner: SelectOwner,
...
};
@@ -278,7 +278,7 @@ function ElementView({isSelected, owner, selectOwner}: ElementViewProps) {
}
type BackToOwnerButtonProps = {|
owners: Array<Owner>,
owners: Array<SerializedElement>,
selectedIndex: number,
selectOwner: SelectOwner,
|};
@@ -44,16 +44,17 @@ export type Element = {|
weight: number,
|};
export type Owner = {|
export type SerializedElement = {|
displayName: string | null,
id: number,
key: number | string | null,
hocDisplayNames: Array<string> | null,
type: ElementType,
|};
export type OwnersList = {|
id: number,
owners: Array<Owner> | null,
owners: Array<SerializedElement> | null,
|};
export type InspectedElementResponseType =
@@ -94,7 +95,7 @@ export type InspectedElement = {|
warnings: Array<[string, number]>,
// List of owners
owners: Array<Owner> | null,
owners: Array<SerializedElement> | null,
// Location of component in source code.
source: Source | null,
@@ -30,6 +30,7 @@
.Interactions {
margin: 0 0 0.5rem;
}
.NoInteractions,
.Interaction {
display: block;
width: 100%;
@@ -45,6 +46,10 @@
background-color: var(--color-background-hover);
}
.NoInteractions {
color: var(--color-dim);
}
.Label {
overflow: hidden;
text-overflow: ellipsis;
@@ -10,8 +10,10 @@
import * as React from 'react';
import {Fragment, useContext} from 'react';
import {ProfilerContext} from './ProfilerContext';
import Updaters from './Updaters';
import {formatDuration, formatTime} from './utils';
import {StoreContext} from '../context';
import {getCommitTree} from './CommitTreeBuilder';
import styles from './SidebarCommitInfo.css';
@@ -39,6 +41,7 @@ export default function SidebarCommitInfo(_: Props) {
passiveEffectDuration,
priorityLevel,
timestamp,
updaters,
} = profilerStore.getCommitData(rootID, selectedCommitIndex);
const viewInteraction = interactionID => {
@@ -49,6 +52,15 @@ export default function SidebarCommitInfo(_: Props) {
const hasCommitPhaseDurations =
effectDuration !== null || passiveEffectDuration !== null;
const commitTree =
updaters !== null
? getCommitTree({
commitIndex: selectedCommitIndex,
profilerStore,
rootID,
})
: null;
return (
<Fragment>
<div className={styles.Toolbar}>Commit information</div>
@@ -102,11 +114,18 @@ export default function SidebarCommitInfo(_: Props) {
</li>
)}
{updaters !== null && commitTree !== null && (
<li className={styles.ListItem}>
<label className={styles.Label}>What caused this update</label>?
<Updaters commitTree={commitTree} updaters={updaters} />
</li>
)}
<li className={styles.Interactions}>
<label className={styles.Label}>Interactions</label>:
<div className={styles.InteractionList}>
{interactionIDs.length === 0 ? (
<div className={styles.NoInteractions}>None</div>
<div className={styles.NoInteractions}>(none)</div>
) : null}
{interactionIDs.map(interactionID => {
const interaction = interactions.get(interactionID);
@@ -0,0 +1,25 @@
.Updaters {
margin: 0 0 0.5rem;
}
.NoUpdaters,
.Updater,
.UnmountedUpdater {
display: block;
width: 100%;
text-align: left;
background: none;
border: none;
padding: 0.25rem 0.5rem;
color: var(--color-text);
}
.Updater:focus,
.Updater:hover {
outline: none;
background-color: var(--color-background-hover);
}
.NoUpdaters,
.UnmountedUpdater {
color: var(--color-dim);
}
@@ -0,0 +1,55 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
import type {CommitTree} from './types';
import type {SerializedElement} from '../Components/types';
import * as React from 'react';
import {useContext} from 'react';
import {ProfilerContext} from './ProfilerContext';
import styles from './Updaters.css';
export type Props = {|
commitTree: CommitTree,
updaters: Array<SerializedElement>,
|};
export default function Updaters({commitTree, updaters}: Props) {
const {selectFiber} = useContext(ProfilerContext);
const children =
updaters.length > 0 ? (
updaters.map<React$Node>((serializedElement: SerializedElement) => {
const {displayName, id, key} = serializedElement;
const isVisibleInTree = commitTree.nodes.has(id);
if (isVisibleInTree) {
return (
<button
key={id}
className={styles.Updater}
onClick={() => selectFiber(id, displayName)}>
{displayName} {key ? `key="${key}"` : ''}
</button>
);
} else {
return (
<div key={id} className={styles.UnmountedUpdater}>
{displayName} {key ? `key="${key}"` : ''}
</div>
);
}
})
) : (
<div key="none" className={styles.NoUpdaters}>
(unknown)
</div>
);
return <div className={styles.Updaters}>{children}</div>;
}
@@ -8,6 +8,7 @@
*/
import type {ElementType} from 'react-devtools-shared/src/types';
import type {SerializedElement} from '../Components/types';
export type CommitTreeNode = {|
id: number,
@@ -80,6 +81,9 @@ export type CommitDataFrontend = {|
// When did this commit occur (relative to the start of profiling)
timestamp: number,
// Fiber(s) responsible for scheduling this update.
updaters: Array<SerializedElement> | null,
|};
export type ProfilingDataForRootFrontend = {|
@@ -131,6 +135,7 @@ export type CommitDataExport = {|
passiveEffectDuration: number | null,
priorityLevel: string | null,
timestamp: number,
updaters: Array<SerializedElement> | null,
|};
export type ProfilingDataForRootExport = {|
@@ -148,6 +153,6 @@ export type ProfilingDataForRootExport = {|
// Serializable version of ProfilingDataFrontend data.
export type ProfilingDataExport = {|
version: 4,
version: 5,
dataForRoots: Array<ProfilingDataForRootExport>,
|};
@@ -8,6 +8,7 @@
*/
import {PROFILER_EXPORT_VERSION} from 'react-devtools-shared/src/constants';
import {separateDisplayNameAndHOCs} from 'react-devtools-shared/src/utils';
import type {ProfilingDataBackend} from 'react-devtools-shared/src/backend/types';
import type {
@@ -84,6 +85,23 @@ export function prepareProfilingDataFrontendFromBackendAndStore(
passiveEffectDuration: commitDataBackend.passiveEffectDuration,
priorityLevel: commitDataBackend.priorityLevel,
timestamp: commitDataBackend.timestamp,
updaters:
commitDataBackend.updaters !== null
? commitDataBackend.updaters.map(serializedElement => {
const [
serializedElementDisplayName,
serializedElementHocDisplayNames,
] = separateDisplayNameAndHOCs(
serializedElement.displayName,
serializedElement.type,
);
return {
...serializedElement,
displayName: serializedElementDisplayName,
hocDisplayNames: serializedElementHocDisplayNames,
};
})
: null,
}),
);
@@ -111,7 +129,9 @@ export function prepareProfilingDataFrontendFromExport(
const {version} = profilingDataExport;
if (version !== PROFILER_EXPORT_VERSION) {
throw Error(`Unsupported profiler export version "${version}"`);
throw Error(
`Unsupported profile export version "${version}". Supported version is "${PROFILER_EXPORT_VERSION}".`,
);
}
const dataForRoots: Map<number, ProfilingDataForRootFrontend> = new Map();
@@ -138,6 +158,7 @@ export function prepareProfilingDataFrontendFromExport(
passiveEffectDuration,
priorityLevel,
timestamp,
updaters,
}) => ({
changeDescriptions:
changeDescriptions != null ? new Map(changeDescriptions) : null,
@@ -149,6 +170,7 @@ export function prepareProfilingDataFrontendFromExport(
passiveEffectDuration,
priorityLevel,
timestamp,
updaters,
}),
),
displayName,
@@ -193,6 +215,7 @@ export function prepareProfilingDataExport(
passiveEffectDuration,
priorityLevel,
timestamp,
updaters,
}) => ({
changeDescriptions:
changeDescriptions != null
@@ -206,6 +229,7 @@ export function prepareProfilingDataExport(
passiveEffectDuration,
priorityLevel,
timestamp,
updaters,
}),
),
displayName,