Merge pull request #274 from bvaughn/commit-priority-level

Show commit priority levels in Profiler UI (if available)
This commit is contained in:
Brian Vaughn
2019-05-20 09:56:58 -07:00
committed by GitHub
14 changed files with 209 additions and 51 deletions
+5 -5
View File
@@ -132,16 +132,16 @@
"opener": "^1.5.1",
"prettier": "^1.16.4",
"prop-types": "^15.6.2",
"react": "^0.0.0-6da04b5d8",
"react": "^0.0.0-50b50c26f",
"react-color": "^2.11.7",
"react-dom": "^0.0.0-6da04b5d8",
"react-is": "^0.0.0-6da04b5d8",
"react-test-renderer": "^0.0.0-6da04b5d8",
"react-dom": "^0.0.0-50b50c26f",
"react-is": "^0.0.0-50b50c26f",
"react-test-renderer": "^0.0.0-50b50c26f",
"react-virtualized-auto-sizer": "^1.0.2",
"react-window": "^1.8.0",
"request-promise": "^4.2.4",
"rimraf": "^2.6.3",
"scheduler": "^0.0.0-6da04b5d8",
"scheduler": "^0.0.0-50b50c26f",
"semver": "^5.5.1",
"style-loader": "^0.23.1",
"web-ext": "^3.0.0",
+7 -11
View File
@@ -6,8 +6,6 @@ import React, {
lazy,
memo,
Component,
// $FlowFixMe Flow thinks ConcurrentMode is stable
unstable_ConcurrentMode as ConcurrentMode,
Fragment,
// $FlowFixMe Flow doesn't know about the Profiler import yet
Profiler,
@@ -48,15 +46,13 @@ export default function ElementTypes() {
<Context.Consumer>{value => null}</Context.Consumer>
</Context.Provider>
<StrictMode>
<ConcurrentMode>
<Suspense fallback={<div>Loading...</div>}>
<ClassComponent />
<FunctionComponent />
<MemoFunctionComponent />
<ForwardRefComponent />
<LazyComponent />
</Suspense>
</ConcurrentMode>
<Suspense fallback={<div>Loading...</div>}>
<ClassComponent />
<FunctionComponent />
<MemoFunctionComponent />
<ForwardRefComponent />
<LazyComponent />
</Suspense>
</StrictMode>
</Fragment>
</Profiler>
+46
View File
@@ -0,0 +1,46 @@
// @flow
import React, { Fragment, useCallback, useState } from 'react';
import {
unstable_IdlePriority as IdlePriority,
unstable_LowPriority as LowPriority,
unstable_runWithPriority as runWithPriority,
} from 'scheduler';
export default function PriorityLevels() {
const [defaultPriority, setDefaultPriority] = useState<boolean>(false);
const [idlePriority, setIdlePriority] = useState<boolean>(false);
const [normalPriority, setLowPriority] = useState<boolean>(false);
const resetSequence = useCallback(() => {
setDefaultPriority(false);
setLowPriority(false);
setIdlePriority(false);
}, []);
const startSequence = useCallback(() => {
setDefaultPriority(true);
runWithPriority(LowPriority, () => setLowPriority(true));
runWithPriority(IdlePriority, () => setIdlePriority(true));
}, []);
const labels = [];
if (defaultPriority) {
labels.push('(default priority)');
}
if (normalPriority) {
labels.push('Low Priority');
}
if (idlePriority) {
labels.push('Idle Priority');
}
return (
<Fragment>
<h1>Priority Levels</h1>
<button onClick={resetSequence}>Reset</button>
<button onClick={startSequence}>Start sequence</button>
<span>{labels.join(', ')}</span>
</Fragment>
);
}
+9 -2
View File
@@ -3,12 +3,17 @@
// This test harness mounts each test app as a separate root to test multi-root applications.
import { createElement } from 'react';
import { render, unmountComponentAtNode } from 'react-dom';
import {
unmountComponentAtNode,
// $FlowFixMe Flow does not yet know about createRoot()
unstable_createRoot as createRoot,
} from 'react-dom';
import DeeplyNestedComponents from './DeeplyNestedComponents';
import EditableProps from './EditableProps';
import ElementTypes from './ElementTypes';
import InspectableElements from './InspectableElements';
import InteractionTracing from './InteractionTracing';
import PriorityLevels from './PriorityLevels';
import ToDoList from './ToDoList';
import Toggle from './Toggle';
import SuspenseTree from './SuspenseTree';
@@ -24,7 +29,8 @@ function mountHelper(App) {
containers.push(container);
render(createElement(App), container);
const root = createRoot(container);
root.render(createElement(App));
}
function mountTestApp() {
@@ -33,6 +39,7 @@ function mountTestApp() {
mountHelper(InspectableElements);
mountHelper(ElementTypes);
mountHelper(EditableProps);
mountHelper(PriorityLevels);
mountHelper(Toggle);
mountHelper(SuspenseTree);
mountHelper(DeeplyNestedComponents);
@@ -27,6 +27,28 @@ exports[`InspectedElementContext should inspect the currently selected element:
}
`;
exports[`InspectedElementContext should inspect the currently selected element: 2: Inspected element 2 2`] = `
{
"id": 2,
"owners": null,
"context": null,
"hooks": [
{
"id": 0,
"isStateEditable": true,
"name": "State",
"value": 1,
"subHooks": []
}
],
"props": {
"foo": 1,
"bar": "abc"
},
"state": null
}
`;
exports[`InspectedElementContext should poll for updates for the currently selected element: 1: mount 1`] = `
[root]
<Example>
@@ -11,6 +11,7 @@ Object {
},
"commitIndex": 0,
"interactions": Array [],
"priorityLevel": "Immediate",
"rootID": 1,
"selfDurations": Map {
1 => 0,
@@ -33,6 +34,7 @@ Object {
},
"commitIndex": 1,
"interactions": Array [],
"priorityLevel": "Immediate",
"rootID": 1,
"selfDurations": Map {
3 => 0,
@@ -53,6 +55,7 @@ Object {
},
"commitIndex": 2,
"interactions": Array [],
"priorityLevel": "Immediate",
"rootID": 1,
"selfDurations": Map {
3 => 0,
@@ -70,6 +73,7 @@ Object {
},
"commitIndex": 3,
"interactions": Array [],
"priorityLevel": "Immediate",
"rootID": 1,
"selfDurations": Map {
2 => 10,
@@ -91,6 +95,7 @@ Object {
},
"commitIndex": 0,
"interactions": Array [],
"priorityLevel": "Immediate",
"rootID": 1,
"selfDurations": Map {
1 => 0,
@@ -110,6 +115,7 @@ Object {
},
"commitIndex": 1,
"interactions": Array [],
"priorityLevel": "Immediate",
"rootID": 1,
"selfDurations": Map {
3 => 0,
@@ -127,6 +133,7 @@ Object {
},
"commitIndex": 2,
"interactions": Array [],
"priorityLevel": "Immediate",
"rootID": 1,
"selfDurations": Map {
3 => 0,
@@ -141,6 +148,7 @@ Object {
},
"commitIndex": 3,
"interactions": Array [],
"priorityLevel": "Immediate",
"rootID": 1,
"selfDurations": Map {
2 => 10,
@@ -324,6 +332,7 @@ Object {
},
"commitIndex": 0,
"interactions": Array [],
"priorityLevel": "Immediate",
"rootID": 1,
"selfDurations": Map {
1 => 0,
@@ -344,6 +353,7 @@ Object {
},
"commitIndex": 0,
"interactions": Array [],
"priorityLevel": "Immediate",
"rootID": 1,
"selfDurations": Map {
1 => 0,
@@ -362,6 +372,7 @@ Object {
},
"commitIndex": 1,
"interactions": Array [],
"priorityLevel": "Immediate",
"rootID": 1,
"selfDurations": Map {
5 => 3,
@@ -447,6 +458,7 @@ Object {
},
"commitIndex": 0,
"interactions": Array [],
"priorityLevel": "Immediate",
"rootID": 1,
"selfDurations": Map {
1 => 0,
@@ -464,6 +476,7 @@ Object {
},
"commitIndex": 1,
"interactions": Array [],
"priorityLevel": "Immediate",
"rootID": 1,
"selfDurations": Map {
3 => 0,
@@ -482,6 +495,7 @@ Object {
},
"commitIndex": 2,
"interactions": Array [],
"priorityLevel": "Immediate",
"rootID": 1,
"selfDurations": Map {
3 => 0,
@@ -696,6 +710,7 @@ Object {
"timestamp": 0,
},
],
"priorityLevel": "Immediate",
"rootID": 1,
"selfDurations": Map {
1 => 0,
@@ -720,6 +735,7 @@ Object {
"timestamp": 11,
},
],
"priorityLevel": "Immediate",
"rootID": 1,
"selfDurations": Map {
3 => 0,
@@ -906,6 +922,7 @@ Object {
},
"commitIndex": 0,
"interactions": Array [],
"priorityLevel": "Immediate",
"rootID": 1,
"selfDurations": Map {
3 => 0,
@@ -923,6 +940,7 @@ Object {
},
"commitIndex": 1,
"interactions": Array [],
"priorityLevel": "Immediate",
"rootID": 1,
"selfDurations": Map {
3 => 0,
@@ -937,6 +955,7 @@ Object {
},
"commitIndex": 2,
"interactions": Array [],
"priorityLevel": "Immediate",
"rootID": 1,
"selfDurations": Map {
2 => 10,
+55 -2
View File
@@ -91,12 +91,27 @@ function getInternalReactConstants(version) {
Placement: 0b10,
};
// **********************************************************
// The section below is copied from files in React repo.
// Keep it in sync, and add version guards if it changes.
//
// Technically these priority levels are invalid for versions before 16.9,
// but 16.9 is the first version to report priority level to DevTools,
// so we can avoid checking for earlier versions and support pre-16.9 canary releases in the process.
const ReactPriorityLevels = {
ImmediatePriority: 99,
UserBlockingPriority: 98,
NormalPriority: 97,
LowPriority: 96,
IdlePriority: 95,
NoPriority: 90,
};
let ReactTypeOfWork;
// **********************************************************
// The section below is copied from files in React repo.
// Keep it in sync, and add version guards if it changes.
// **********************************************************
if (gte(version, '16.6.0-beta.0')) {
ReactTypeOfWork = {
ClassComponent: 1,
@@ -184,6 +199,7 @@ function getInternalReactConstants(version) {
// **********************************************************
return {
ReactPriorityLevels,
ReactTypeOfWork,
ReactSymbols,
ReactTypeOfSideEffect,
@@ -197,6 +213,7 @@ export function attach(
global: Object
): RendererInterface {
const {
ReactPriorityLevels,
ReactTypeOfWork,
ReactSymbols,
ReactTypeOfSideEffect,
@@ -221,6 +238,14 @@ export function attach(
SimpleMemoComponent,
SuspenseComponent,
} = ReactTypeOfWork;
const {
ImmediatePriority,
UserBlockingPriority,
NormalPriority,
LowPriority,
IdlePriority,
NoPriority,
} = ReactPriorityLevels;
const {
CONCURRENT_MODE_NUMBER,
CONCURRENT_MODE_SYMBOL_STRING,
@@ -1267,6 +1292,7 @@ export function attach(
})
),
maxActualDuration: 0,
priorityLevel: null,
};
}
@@ -1284,7 +1310,7 @@ export function attach(
recordUnmount(fiber, false);
}
function handleCommitFiberRoot(root) {
function handleCommitFiberRoot(root, priorityLevel) {
const current = root.current;
const alternate = current.alternate;
@@ -1309,6 +1335,8 @@ export function attach(
})
),
maxActualDuration: 0,
priorityLevel:
priorityLevel == null ? null : formatPriorityLevel(priorityLevel),
};
}
@@ -1955,6 +1983,7 @@ export function attach(
durations: Array<number>,
interactions: Array<InteractionBackend>,
maxActualDuration: number,
priorityLevel: string | null,
|};
type CommitProfilingMetadataMap = Map<number, Array<CommitProfilingData>>;
@@ -1980,6 +2009,7 @@ export function attach(
commitIndex,
durations: commitProfilingData.durations,
interactions: commitProfilingData.interactions,
priorityLevel: commitProfilingData.priorityLevel,
rootID,
};
}
@@ -1993,6 +2023,7 @@ export function attach(
commitIndex,
durations: [],
interactions: [],
priorityLevel: null,
rootID,
};
}
@@ -2402,6 +2433,28 @@ export function attach(
};
}
const formatPriorityLevel = (priorityLevel: ?number) => {
if (priorityLevel == null) {
return 'Unknown';
}
switch (priorityLevel) {
case ImmediatePriority:
return 'Immediate';
case UserBlockingPriority:
return 'User-Blocking';
case NormalPriority:
return 'Normal';
case LowPriority:
return 'Low';
case IdlePriority:
return 'Idle';
case NoPriority:
default:
return 'Unknown';
}
};
return {
cleanup,
flushInitialOperations,
+7 -2
View File
@@ -126,6 +126,7 @@ export type CommitDetailsBackend = {|
// An interleaved array: fiberID at [i], actualDuration at [i + 1], computed selfDuration at [i + 2].
durations: Array<number>,
interactions: Array<InteractionBackend>,
priorityLevel: string | null,
rootID: number,
|};
@@ -193,7 +194,7 @@ export type RendererInterface = {
) => ExportedProfilingDataFromRenderer,
getProfilingSummary: (rootID: number) => ProfilingSummaryBackend,
getPathForElement: (id: number) => Array<PathFrame> | null,
handleCommitFiberRoot: (fiber: Object) => void,
handleCommitFiberRoot: (fiber: Object, commitPriority?: number) => void,
handleCommitFiberUnmount: (fiber: Object) => void,
inspectElement: (id: number) => InspectedElement | null,
logElementToConsole: (id: number) => void,
@@ -234,7 +235,11 @@ export type DevToolsHook = {
// React uses these methods.
checkDCE: (fn: Function) => void,
onCommitFiberUnmount: (rendererID: RendererID, fiber: Object) => void,
onCommitFiberRoot: (rendererID: RendererID, fiber: Object) => void,
onCommitFiberRoot: (
rendererID: RendererID,
fiber: Object,
commitPriority?: number
) => void,
};
export type HooksNode = {
+4 -1
View File
@@ -130,8 +130,9 @@ export default class ProfilingCache {
rootID,
commitIndex,
actualDurations: new Map(),
selfDurations: new Map(),
priorityLevel: null,
interactions: [],
selfDurations: new Map(),
});
});
},
@@ -346,6 +347,7 @@ export default class ProfilingCache {
commitIndex,
durations,
interactions,
priorityLevel,
rootID,
}: CommitDetailsBackend) => {
const key = `${rootID}-${commitIndex}`;
@@ -365,6 +367,7 @@ export default class ProfilingCache {
actualDurations: actualDurationsMap,
commitIndex,
interactions,
priorityLevel,
rootID,
selfDurations: selfDurationsMap,
});
@@ -56,7 +56,7 @@ export default function SidebarCommitInfo(_: Props) {
}
);
const { interactions } = profilingCache.CommitDetails.read({
const { interactions, priorityLevel } = profilingCache.CommitDetails.read({
commitIndex: selectedCommitIndex,
rendererID: ((rendererID: any): number),
rootID: ((rootID: any): number),
@@ -72,6 +72,12 @@ export default function SidebarCommitInfo(_: Props) {
<div className={styles.Toolbar}>Commit information</div>
<div className={styles.Content}>
<ul className={styles.List}>
{priorityLevel !== null && (
<li className={styles.ListItem}>
<label className={styles.Label}>Priority</label>:{' '}
<span className={styles.Value}>{priorityLevel}</span>
</li>
)}
<li className={styles.ListItem}>
<label className={styles.Label}>Committed at</label>:{' '}
<span className={styles.Value}>
+1
View File
@@ -42,6 +42,7 @@ export type CommitDetailsFrontend = {|
actualDurations: Map<number, number>,
commitIndex: number,
interactions: Array<InteractionFrontend>,
priorityLevel: string | null,
rootID: number,
selfDurations: Map<number, number>,
|};
+2 -1
View File
@@ -152,10 +152,11 @@ export const prepareImportedProfilingData = (
}
return {
actualDurations: actualDurationsMap,
selfDurations: selfDurationsMap,
commitIndex: commitDetailsBackendItem.commitIndex,
interactions: commitDetailsBackendItem.interactions,
priorityLevel: commitDetailsBackendItem.priorityLevel,
rootID: commitDetailsBackendItem.rootID,
selfDurations: selfDurationsMap,
};
}
),
+2 -2
View File
@@ -138,7 +138,7 @@ export function installHook(target: any): DevToolsHook | null {
}
}
function onCommitFiberRoot(rendererID, root) {
function onCommitFiberRoot(rendererID, root, priorityLevel) {
const mountedRoots = hook.getFiberRoots(rendererID);
const current = root.current;
const isKnownRoot = mountedRoots.has(root);
@@ -153,7 +153,7 @@ export function installHook(target: any): DevToolsHook | null {
}
const rendererInterface = rendererInterfaces.get(rendererID);
if (rendererInterface != null) {
rendererInterface.handleCommitFiberRoot(root);
rendererInterface.handleCommitFiberRoot(root, priorityLevel);
}
}
+23 -24
View File
@@ -9748,20 +9748,20 @@ react-color@^2.11.7:
reactcss "^1.2.0"
tinycolor2 "^1.4.1"
react-dom@^0.0.0-6da04b5d8:
version "0.0.0-6da04b5d8"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-0.0.0-6da04b5d8.tgz#ee78e45a40771560c756b8fc7f1fa213f2179ebe"
integrity sha512-6oyfkucrweqCB5XyLsfEnPSWhvkFnttutkU9uUQovLAljuazgpAjvBy6MBGSewKptqch2OTNwopqvR3QUMD8AQ==
react-dom@^0.0.0-50b50c26f:
version "0.0.0-50b50c26f"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-0.0.0-50b50c26f.tgz#3cd8da0f2276ed4b7a926e1807d2675b2eb40227"
integrity sha512-da9qleWDdBdAguEIDvvpFE0iuS8hfcCSGgZTYKRQMlSh5A94Ktr1otL4rgDTFH+bNsOwz3XrvEBYRA6WaE9xzQ==
dependencies:
loose-envify "^1.1.0"
object-assign "^4.1.1"
prop-types "^15.6.2"
scheduler "0.0.0-6da04b5d8"
scheduler "0.0.0-50b50c26f"
react-is@0.0.0-6da04b5d8, react-is@^0.0.0-6da04b5d8:
version "0.0.0-6da04b5d8"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-0.0.0-6da04b5d8.tgz#ded1f02e9f1e2b8456812d0d45c341d70b7bf7db"
integrity sha512-+Df3meqx+XUir+3dCqiHNAHruwmOAgXVp3TYmlUvgtPNBu+LF0OdchTMZ/xMUok1gYVoe4l/xhfs9CTEPkWt3g==
react-is@0.0.0-50b50c26f, react-is@^0.0.0-50b50c26f:
version "0.0.0-50b50c26f"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-0.0.0-50b50c26f.tgz#c4003ffffef9bd2b287979f9041a23d12a607bf2"
integrity sha512-9Y6ZvdOVmOxXs9mGuFy6eXHBww8RJCtJAh94b1hkbjhnW8Mb5ADScDoxJBVxcNuX9hvDkhENspC96ZQK1NIv3g==
react-is@^16.8.1:
version "16.8.3"
@@ -9773,15 +9773,15 @@ react-is@^16.8.4:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.4.tgz#90f336a68c3a29a096a3d648ab80e87ec61482a2"
integrity sha512-PVadd+WaUDOAciICm/J1waJaSvgq+4rHE/K70j0PFqKhkTBsPv/82UGQJNXAngz1fOQLLxI6z1sEDmJDQhCTAA==
react-test-renderer@^0.0.0-6da04b5d8:
version "0.0.0-6da04b5d8"
resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-0.0.0-6da04b5d8.tgz#01bed04c5a4cf22339f0ae3b23f89bb45e9a8f2a"
integrity sha512-yDt5RPDXLZXTqlWS0jXMJ1IyS1e/UZXSr0L8bG0UCsna4T7A3HIYR2zChlydGXsxjGMZntKqEfm27hUhFgC06Q==
react-test-renderer@^0.0.0-50b50c26f:
version "0.0.0-50b50c26f"
resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-0.0.0-50b50c26f.tgz#1a85cf9073ef5a932d03bee36fcfd9bf15aeae2c"
integrity sha512-gWc4L+mFIUCjvBpafR88n4/i/oaKHD6rzVyZY+XBou9MNtr2rRkjePOhBVsiYlCwkj+zZi6klV9b05TMzftosA==
dependencies:
object-assign "^4.1.1"
prop-types "^15.6.2"
react-is "0.0.0-6da04b5d8"
scheduler "0.0.0-6da04b5d8"
react-is "0.0.0-50b50c26f"
scheduler "0.0.0-50b50c26f"
react-virtualized-auto-sizer@^1.0.2:
version "1.0.2"
@@ -9796,15 +9796,14 @@ react-window@^1.8.0:
"@babel/runtime" "^7.0.0"
memoize-one ">=3.1.1 <6"
react@^0.0.0-6da04b5d8:
version "0.0.0-6da04b5d8"
resolved "https://registry.yarnpkg.com/react/-/react-0.0.0-6da04b5d8.tgz#583d81f73b26771da41170a5042a5ab0bdcfe37a"
integrity sha512-8hXBHwDCKxSVFqj5Kb4OskZz7//2fx2IpUnYyukYV8qyAHlXr0qUl3GxwuryhdPzJHlzi776WjN0YEmEEANhYA==
react@^0.0.0-50b50c26f:
version "0.0.0-50b50c26f"
resolved "https://registry.yarnpkg.com/react/-/react-0.0.0-50b50c26f.tgz#b782b579ce1f5d8bd696c5e45c744714ebecb111"
integrity sha512-jUAzS4DeWTdUZ/3kqm2T6C9OIpiAf2qdwVamCts0qzwYVni1/gUTOWK1ui0J+eaRzKxrIEzVvmCMxFd35lP/pA==
dependencies:
loose-envify "^1.1.0"
object-assign "^4.1.1"
prop-types "^15.6.2"
scheduler "0.0.0-6da04b5d8"
reactcss@^1.2.0:
version "1.2.3"
@@ -10460,10 +10459,10 @@ sax@>=0.6.0, sax@^1.2.4:
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
scheduler@0.0.0-6da04b5d8, scheduler@^0.0.0-6da04b5d8:
version "0.0.0-6da04b5d8"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.0.0-6da04b5d8.tgz#5e0ec65c2b0a7f05ffdc5522fc3a6d95b693e5c9"
integrity sha512-upTrWBZvk4IjMsC/AcRpgCwjnSQl8i78+07KmcndqWOnWp7s4wauowWXhyswP9vucLtZaN5ussFdM3d7dXcTkw==
scheduler@0.0.0-50b50c26f, scheduler@^0.0.0-50b50c26f:
version "0.0.0-50b50c26f"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.0.0-50b50c26f.tgz#09bedde1c64d7a042b557bee2dbf5faf5fd58a50"
integrity sha512-LBN3zrP8iBdILOoYxybFtkU7j+ldZTHORKyYyVLwXuIwGQ8/Xhs5VZjNQ5R2Xru2zv3GGVpJSbd47EpDuD2EHw==
dependencies:
loose-envify "^1.1.0"
object-assign "^4.1.1"