Fixed some missing operations that could happen after reload-and-profile

This commit is contained in:
Brian Vaughn
2019-04-01 14:29:52 -07:00
parent 74cd1a5d29
commit f5f7cb5bdf
6 changed files with 65 additions and 33 deletions

View File

@@ -23,7 +23,10 @@ export function initBackend(
rendererInterface: RendererInterface,
}) => {
agent.setRendererInterface(id, rendererInterface);
rendererInterface.walkTree();
// Now that the Store and the renderer interface are connected,
// it's time to flush the pending operation codes to the frontend.
rendererInterface.flushInitialOperations();
}
),

View File

@@ -567,6 +567,7 @@ export function attach(
}
let pendingOperations: Uint32Array = new Uint32Array(0);
let pendingOperationsQueue: Array<Uint32Array> | null = [];
function addOperation(
newAction: Uint32Array,
@@ -604,7 +605,16 @@ export function attach(
// Let the frontend know about tree operations.
// The first value in this array will identify which root it corresponds to,
// so we do no longer need to dispatch a separate root-committed event.
hook.emit('operations', pendingOperations);
if (pendingOperationsQueue !== null) {
// Until the frontend has been connected, store the tree operations.
// This will let us avoid walking the tree later when the frontend connects,
// and it enables the Profiler's reload-and-profile functionality to work as well.
pendingOperationsQueue.push(pendingOperations);
} else {
// If we've already connected to the frontend, just pass the operations through.
hook.emit('operations', pendingOperations);
}
pendingOperations = new Uint32Array(0);
}
@@ -914,31 +924,46 @@ export function attach(
// We don't patch any methods so there is no cleanup.
}
function walkTree() {
// Hydrate all the roots for the first time.
hook.getFiberRoots(rendererID).forEach(root => {
currentRootID = getFiberID(getPrimaryFiber(root.current));
function flushInitialOperations() {
const localPendingOperationsQueue = pendingOperationsQueue;
if (isProfiling) {
// If profiling is active, store commit time and duration, and the current interactions.
// The frontend may request this information after profiling has stopped.
currentCommitProfilingMetadata = {
actualDurations: [],
commitTime: performance.now() - profilingStartTime,
interactions: Array.from(root.memoizedInteractions).map(
(interaction: Interaction) => ({
...interaction,
timestamp: interaction.timestamp - profilingStartTime,
})
),
maxActualDuration: 0,
};
}
pendingOperationsQueue = null;
mountFiber(root.current, null);
flushPendingEvents(root);
currentRootID = -1;
});
if (
localPendingOperationsQueue !== null &&
localPendingOperationsQueue.length > 0
) {
// We may have already queued up some operations before the frontend connected
// If so, let the frontend know about them.
localPendingOperationsQueue.forEach(pendingOperations => {
hook.emit('operations', pendingOperations);
});
} else {
// If we have not been profiling, then we can just walk the tree and build up its current state as-is.
hook.getFiberRoots(rendererID).forEach(root => {
currentRootID = getFiberID(getPrimaryFiber(root.current));
if (isProfiling) {
// If profiling is active, store commit time and duration, and the current interactions.
// The frontend may request this information after profiling has stopped.
currentCommitProfilingMetadata = {
actualDurations: [],
commitTime: performance.now() - profilingStartTime,
interactions: Array.from(root.memoizedInteractions).map(
(interaction: Interaction) => ({
...interaction,
timestamp: interaction.timestamp - profilingStartTime,
})
),
maxActualDuration: 0,
};
}
mountFiber(root.current, null);
flushPendingEvents(root);
currentRootID = -1;
});
}
}
function handleCommitFiberUnmount(fiber) {
@@ -1623,6 +1648,7 @@ export function attach(
return {
cleanup,
flushInitialOperations,
getCommitDetails,
getFiberIDFromNative,
getInteractions,
@@ -1641,6 +1667,5 @@ export function attach(
setInState,
startProfiling,
stopProfiling,
walkTree,
};
}

View File

@@ -82,6 +82,7 @@ export type ProfilingSummary = {|
export type RendererInterface = {
cleanup: () => void,
flushInitialOperations: () => void,
getCommitDetails: (rootID: number, commitIndex: number) => CommitDetails,
getNativeFromReactElement?: ?(component: Fiber) => ?NativeType,
getFiberIDFromNative: (
@@ -108,7 +109,6 @@ export type RendererInterface = {
setInState: (id: number, path: Array<string | number>, value: any) => void,
startProfiling: () => void,
stopProfiling: () => void,
walkTree: () => void,
};
export type Handler = (data: any) => void;

View File

@@ -112,14 +112,9 @@ export function getCommitTree({
}
}
console.error(
throw Error(
`getCommitTree(): Unable to reconstruct tree for root "${rootID}" and commit ${commitIndex}`
);
return {
nodes: new Map(),
rootID,
};
}
function recursivelyIniitliazeTree(

View File

@@ -56,6 +56,11 @@ export function getChartData({
idToDepthMap.set(id, currentDepth);
const node = ((nodes.get(id): any): Node);
if (node == null) {
throw Error(`Could not find node with id "${id}" in commit tree`);
}
const name = node.displayName || 'Unknown';
const selfDuration = calculateSelfDuration(id, commitTree, commitDetails);

View File

@@ -41,6 +41,10 @@ export function getChartData({
actualDurations.forEach((actualDuration, id) => {
const node = ((nodes.get(id): any): Node);
if (node == null) {
throw Error(`Could not find node with id "${id}" in commit tree`);
}
// Don't show the root node in this chart.
if (node.parentID === 0) {
return;