mirror of
https://github.com/hanzoai/react.git
synced 2026-09-24 17:02:27 +00:00
Include ReactDebugTool from inside __DEV__ to save 1.5KB (#8322)
This commit is contained in:
committed by
Ben Alpert
parent
12f8898edf
commit
cbc87cd828
@@ -63,357 +63,362 @@ type HistoryItem = {
|
||||
|
||||
export type FlushHistory = Array<HistoryItem>;
|
||||
|
||||
var hooks = [];
|
||||
var didHookThrowForEvent = {};
|
||||
// Trust the developer to only use this with a __DEV__ check
|
||||
var ReactDebugTool = ((null: any): typeof ReactDebugTool);
|
||||
|
||||
function callHook(event, fn, context, arg1, arg2, arg3, arg4, arg5) {
|
||||
try {
|
||||
fn.call(context, arg1, arg2, arg3, arg4, arg5);
|
||||
} catch (e) {
|
||||
warning(
|
||||
didHookThrowForEvent[event],
|
||||
'Exception thrown by hook while handling %s: %s',
|
||||
event,
|
||||
e + '\n' + e.stack
|
||||
);
|
||||
didHookThrowForEvent[event] = true;
|
||||
}
|
||||
}
|
||||
if (__DEV__) {
|
||||
var hooks = [];
|
||||
var didHookThrowForEvent = {};
|
||||
|
||||
function emitEvent(event, arg1, arg2, arg3, arg4, arg5) {
|
||||
for (var i = 0; i < hooks.length; i++) {
|
||||
var hook = hooks[i];
|
||||
var fn = hook[event];
|
||||
if (fn) {
|
||||
callHook(event, fn, hook, arg1, arg2, arg3, arg4, arg5);
|
||||
const callHook = function(event, fn, context, arg1, arg2, arg3, arg4, arg5) {
|
||||
try {
|
||||
fn.call(context, arg1, arg2, arg3, arg4, arg5);
|
||||
} catch (e) {
|
||||
warning(
|
||||
didHookThrowForEvent[event],
|
||||
'Exception thrown by hook while handling %s: %s',
|
||||
event,
|
||||
e + '\n' + e.stack
|
||||
);
|
||||
didHookThrowForEvent[event] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var isProfiling = false;
|
||||
var flushHistory = [];
|
||||
var lifeCycleTimerStack = [];
|
||||
var currentFlushNesting = 0;
|
||||
var currentFlushMeasurements = [];
|
||||
var currentFlushStartTime = 0;
|
||||
var currentTimerDebugID = null;
|
||||
var currentTimerStartTime = 0;
|
||||
var currentTimerNestedFlushDuration = 0;
|
||||
var currentTimerType = null;
|
||||
|
||||
var lifeCycleTimerHasWarned = false;
|
||||
|
||||
function clearHistory() {
|
||||
ReactComponentTreeHook.purgeUnmountedComponents();
|
||||
ReactHostOperationHistoryHook.clearHistory();
|
||||
}
|
||||
|
||||
function getTreeSnapshot(registeredIDs) {
|
||||
return registeredIDs.reduce((tree, id) => {
|
||||
var ownerID = ReactComponentTreeHook.getOwnerID(id);
|
||||
var parentID = ReactComponentTreeHook.getParentID(id);
|
||||
tree[id] = {
|
||||
displayName: ReactComponentTreeHook.getDisplayName(id),
|
||||
text: ReactComponentTreeHook.getText(id),
|
||||
updateCount: ReactComponentTreeHook.getUpdateCount(id),
|
||||
childIDs: ReactComponentTreeHook.getChildIDs(id),
|
||||
// Text nodes don't have owners but this is close enough.
|
||||
ownerID: ownerID ||
|
||||
parentID && ReactComponentTreeHook.getOwnerID(parentID) ||
|
||||
0,
|
||||
parentID,
|
||||
};
|
||||
return tree;
|
||||
}, {});
|
||||
}
|
||||
|
||||
function resetMeasurements() {
|
||||
var previousStartTime = currentFlushStartTime;
|
||||
var previousMeasurements = currentFlushMeasurements;
|
||||
var previousOperations = ReactHostOperationHistoryHook.getHistory();
|
||||
|
||||
if (currentFlushNesting === 0) {
|
||||
currentFlushStartTime = 0;
|
||||
currentFlushMeasurements = [];
|
||||
clearHistory();
|
||||
return;
|
||||
}
|
||||
|
||||
if (previousMeasurements.length || previousOperations.length) {
|
||||
var registeredIDs = ReactComponentTreeHook.getRegisteredIDs();
|
||||
flushHistory.push({
|
||||
duration: performanceNow() - previousStartTime,
|
||||
measurements: previousMeasurements || [],
|
||||
operations: previousOperations || [],
|
||||
treeSnapshot: getTreeSnapshot(registeredIDs),
|
||||
});
|
||||
}
|
||||
|
||||
clearHistory();
|
||||
currentFlushStartTime = performanceNow();
|
||||
currentFlushMeasurements = [];
|
||||
}
|
||||
|
||||
function checkDebugID(debugID, allowRoot = false) {
|
||||
if (allowRoot && debugID === 0) {
|
||||
return;
|
||||
}
|
||||
if (!debugID) {
|
||||
warning(false, 'ReactDebugTool: debugID may not be empty.');
|
||||
}
|
||||
}
|
||||
|
||||
function beginLifeCycleTimer(debugID, timerType) {
|
||||
if (currentFlushNesting === 0) {
|
||||
return;
|
||||
}
|
||||
if (currentTimerType && !lifeCycleTimerHasWarned) {
|
||||
warning(
|
||||
false,
|
||||
'There is an internal error in the React performance measurement code. ' +
|
||||
'Did not expect %s timer to start while %s timer is still in ' +
|
||||
'progress for %s instance.',
|
||||
timerType,
|
||||
currentTimerType || 'no',
|
||||
(debugID === currentTimerDebugID) ? 'the same' : 'another'
|
||||
);
|
||||
lifeCycleTimerHasWarned = true;
|
||||
}
|
||||
currentTimerStartTime = performanceNow();
|
||||
currentTimerNestedFlushDuration = 0;
|
||||
currentTimerDebugID = debugID;
|
||||
currentTimerType = timerType;
|
||||
}
|
||||
|
||||
function endLifeCycleTimer(debugID, timerType) {
|
||||
if (currentFlushNesting === 0) {
|
||||
return;
|
||||
}
|
||||
if (currentTimerType !== timerType && !lifeCycleTimerHasWarned) {
|
||||
warning(
|
||||
false,
|
||||
'There is an internal error in the React performance measurement code. ' +
|
||||
'We did not expect %s timer to stop while %s timer is still in ' +
|
||||
'progress for %s instance. Please report this as a bug in React.',
|
||||
timerType,
|
||||
currentTimerType || 'no',
|
||||
(debugID === currentTimerDebugID) ? 'the same' : 'another'
|
||||
);
|
||||
lifeCycleTimerHasWarned = true;
|
||||
}
|
||||
if (isProfiling) {
|
||||
currentFlushMeasurements.push({
|
||||
timerType,
|
||||
instanceID: debugID,
|
||||
duration: performanceNow() - currentTimerStartTime - currentTimerNestedFlushDuration,
|
||||
});
|
||||
}
|
||||
currentTimerStartTime = 0;
|
||||
currentTimerNestedFlushDuration = 0;
|
||||
currentTimerDebugID = null;
|
||||
currentTimerType = null;
|
||||
}
|
||||
|
||||
function pauseCurrentLifeCycleTimer() {
|
||||
var currentTimer = {
|
||||
startTime: currentTimerStartTime,
|
||||
nestedFlushStartTime: performanceNow(),
|
||||
debugID: currentTimerDebugID,
|
||||
timerType: currentTimerType,
|
||||
};
|
||||
lifeCycleTimerStack.push(currentTimer);
|
||||
currentTimerStartTime = 0;
|
||||
currentTimerNestedFlushDuration = 0;
|
||||
currentTimerDebugID = null;
|
||||
currentTimerType = null;
|
||||
}
|
||||
|
||||
function resumeCurrentLifeCycleTimer() {
|
||||
var {startTime, nestedFlushStartTime, debugID, timerType} = lifeCycleTimerStack.pop();
|
||||
var nestedFlushDuration = performanceNow() - nestedFlushStartTime;
|
||||
currentTimerStartTime = startTime;
|
||||
currentTimerNestedFlushDuration += nestedFlushDuration;
|
||||
currentTimerDebugID = debugID;
|
||||
currentTimerType = timerType;
|
||||
}
|
||||
|
||||
var lastMarkTimeStamp = 0;
|
||||
var canUsePerformanceMeasure: boolean =
|
||||
typeof performance !== 'undefined' &&
|
||||
typeof performance.mark === 'function' &&
|
||||
typeof performance.clearMarks === 'function' &&
|
||||
typeof performance.measure === 'function' &&
|
||||
typeof performance.clearMeasures === 'function';
|
||||
|
||||
function shouldMark(debugID) {
|
||||
if (!isProfiling || !canUsePerformanceMeasure) {
|
||||
return false;
|
||||
}
|
||||
var element = ReactComponentTreeHook.getElement(debugID);
|
||||
if (element == null || typeof element !== 'object') {
|
||||
return false;
|
||||
}
|
||||
var isHostElement = typeof element.type === 'string';
|
||||
if (isHostElement) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function markBegin(debugID, markType) {
|
||||
if (!shouldMark(debugID)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var markName = `${debugID}::${markType}`;
|
||||
lastMarkTimeStamp = performanceNow();
|
||||
performance.mark(markName);
|
||||
}
|
||||
|
||||
function markEnd(debugID, markType) {
|
||||
if (!shouldMark(debugID)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var markName = `${debugID}::${markType}`;
|
||||
var displayName = ReactComponentTreeHook.getDisplayName(debugID) || 'Unknown';
|
||||
|
||||
// Chrome has an issue of dropping markers recorded too fast:
|
||||
// https://bugs.chromium.org/p/chromium/issues/detail?id=640652
|
||||
// To work around this, we will not report very small measurements.
|
||||
// I determined the magic number by tweaking it back and forth.
|
||||
// 0.05ms was enough to prevent the issue, but I set it to 0.1ms to be safe.
|
||||
// When the bug is fixed, we can `measure()` unconditionally if we want to.
|
||||
var timeStamp = performanceNow();
|
||||
if (timeStamp - lastMarkTimeStamp > 0.1) {
|
||||
var measurementName = `${displayName} [${markType}]`;
|
||||
performance.measure(measurementName, markName);
|
||||
}
|
||||
|
||||
performance.clearMarks(markName);
|
||||
performance.clearMeasures(measurementName);
|
||||
}
|
||||
|
||||
var ReactDebugTool = {
|
||||
addHook(hook: Hook): void {
|
||||
hooks.push(hook);
|
||||
},
|
||||
removeHook(hook: Hook): void {
|
||||
const emitEvent = function(event, arg1, arg2, arg3, arg4, arg5) {
|
||||
for (var i = 0; i < hooks.length; i++) {
|
||||
if (hooks[i] === hook) {
|
||||
hooks.splice(i, 1);
|
||||
i--;
|
||||
var hook = hooks[i];
|
||||
var fn = hook[event];
|
||||
if (fn) {
|
||||
callHook(event, fn, hook, arg1, arg2, arg3, arg4, arg5);
|
||||
}
|
||||
}
|
||||
},
|
||||
isProfiling(): boolean {
|
||||
return isProfiling;
|
||||
},
|
||||
beginProfiling(): void {
|
||||
};
|
||||
|
||||
var isProfiling = false;
|
||||
var flushHistory = [];
|
||||
var lifeCycleTimerStack = [];
|
||||
var currentFlushNesting = 0;
|
||||
var currentFlushMeasurements = [];
|
||||
var currentFlushStartTime = 0;
|
||||
var currentTimerDebugID = null;
|
||||
var currentTimerStartTime = 0;
|
||||
var currentTimerNestedFlushDuration = 0;
|
||||
var currentTimerType = null;
|
||||
|
||||
var lifeCycleTimerHasWarned = false;
|
||||
|
||||
const clearHistory = function() {
|
||||
ReactComponentTreeHook.purgeUnmountedComponents();
|
||||
ReactHostOperationHistoryHook.clearHistory();
|
||||
};
|
||||
|
||||
const getTreeSnapshot = function(registeredIDs) {
|
||||
return registeredIDs.reduce((tree, id) => {
|
||||
var ownerID = ReactComponentTreeHook.getOwnerID(id);
|
||||
var parentID = ReactComponentTreeHook.getParentID(id);
|
||||
tree[id] = {
|
||||
displayName: ReactComponentTreeHook.getDisplayName(id),
|
||||
text: ReactComponentTreeHook.getText(id),
|
||||
updateCount: ReactComponentTreeHook.getUpdateCount(id),
|
||||
childIDs: ReactComponentTreeHook.getChildIDs(id),
|
||||
// Text nodes don't have owners but this is close enough.
|
||||
ownerID: ownerID ||
|
||||
parentID && ReactComponentTreeHook.getOwnerID(parentID) ||
|
||||
0,
|
||||
parentID,
|
||||
};
|
||||
return tree;
|
||||
}, {});
|
||||
};
|
||||
|
||||
const resetMeasurements = function() {
|
||||
var previousStartTime = currentFlushStartTime;
|
||||
var previousMeasurements = currentFlushMeasurements;
|
||||
var previousOperations = ReactHostOperationHistoryHook.getHistory();
|
||||
|
||||
if (currentFlushNesting === 0) {
|
||||
currentFlushStartTime = 0;
|
||||
currentFlushMeasurements = [];
|
||||
clearHistory();
|
||||
return;
|
||||
}
|
||||
|
||||
if (previousMeasurements.length || previousOperations.length) {
|
||||
var registeredIDs = ReactComponentTreeHook.getRegisteredIDs();
|
||||
flushHistory.push({
|
||||
duration: performanceNow() - previousStartTime,
|
||||
measurements: previousMeasurements || [],
|
||||
operations: previousOperations || [],
|
||||
treeSnapshot: getTreeSnapshot(registeredIDs),
|
||||
});
|
||||
}
|
||||
|
||||
clearHistory();
|
||||
currentFlushStartTime = performanceNow();
|
||||
currentFlushMeasurements = [];
|
||||
};
|
||||
|
||||
const checkDebugID = function(debugID, allowRoot = false) {
|
||||
if (allowRoot && debugID === 0) {
|
||||
return;
|
||||
}
|
||||
if (!debugID) {
|
||||
warning(false, 'ReactDebugTool: debugID may not be empty.');
|
||||
}
|
||||
};
|
||||
|
||||
const beginLifeCycleTimer = function(debugID, timerType) {
|
||||
if (currentFlushNesting === 0) {
|
||||
return;
|
||||
}
|
||||
if (currentTimerType && !lifeCycleTimerHasWarned) {
|
||||
warning(
|
||||
false,
|
||||
'There is an internal error in the React performance measurement code. ' +
|
||||
'Did not expect %s timer to start while %s timer is still in ' +
|
||||
'progress for %s instance.',
|
||||
timerType,
|
||||
currentTimerType || 'no',
|
||||
(debugID === currentTimerDebugID) ? 'the same' : 'another'
|
||||
);
|
||||
lifeCycleTimerHasWarned = true;
|
||||
}
|
||||
currentTimerStartTime = performanceNow();
|
||||
currentTimerNestedFlushDuration = 0;
|
||||
currentTimerDebugID = debugID;
|
||||
currentTimerType = timerType;
|
||||
};
|
||||
|
||||
const endLifeCycleTimer = function(debugID, timerType) {
|
||||
if (currentFlushNesting === 0) {
|
||||
return;
|
||||
}
|
||||
if (currentTimerType !== timerType && !lifeCycleTimerHasWarned) {
|
||||
warning(
|
||||
false,
|
||||
'There is an internal error in the React performance measurement code. ' +
|
||||
'We did not expect %s timer to stop while %s timer is still in ' +
|
||||
'progress for %s instance. Please report this as a bug in React.',
|
||||
timerType,
|
||||
currentTimerType || 'no',
|
||||
(debugID === currentTimerDebugID) ? 'the same' : 'another'
|
||||
);
|
||||
lifeCycleTimerHasWarned = true;
|
||||
}
|
||||
if (isProfiling) {
|
||||
currentFlushMeasurements.push({
|
||||
timerType,
|
||||
instanceID: debugID,
|
||||
duration: performanceNow() - currentTimerStartTime - currentTimerNestedFlushDuration,
|
||||
});
|
||||
}
|
||||
currentTimerStartTime = 0;
|
||||
currentTimerNestedFlushDuration = 0;
|
||||
currentTimerDebugID = null;
|
||||
currentTimerType = null;
|
||||
};
|
||||
|
||||
const pauseCurrentLifeCycleTimer = function() {
|
||||
var currentTimer = {
|
||||
startTime: currentTimerStartTime,
|
||||
nestedFlushStartTime: performanceNow(),
|
||||
debugID: currentTimerDebugID,
|
||||
timerType: currentTimerType,
|
||||
};
|
||||
lifeCycleTimerStack.push(currentTimer);
|
||||
currentTimerStartTime = 0;
|
||||
currentTimerNestedFlushDuration = 0;
|
||||
currentTimerDebugID = null;
|
||||
currentTimerType = null;
|
||||
};
|
||||
|
||||
const resumeCurrentLifeCycleTimer = function() {
|
||||
var {startTime, nestedFlushStartTime, debugID, timerType} = lifeCycleTimerStack.pop();
|
||||
var nestedFlushDuration = performanceNow() - nestedFlushStartTime;
|
||||
currentTimerStartTime = startTime;
|
||||
currentTimerNestedFlushDuration += nestedFlushDuration;
|
||||
currentTimerDebugID = debugID;
|
||||
currentTimerType = timerType;
|
||||
};
|
||||
|
||||
var lastMarkTimeStamp = 0;
|
||||
var canUsePerformanceMeasure: boolean =
|
||||
typeof performance !== 'undefined' &&
|
||||
typeof performance.mark === 'function' &&
|
||||
typeof performance.clearMarks === 'function' &&
|
||||
typeof performance.measure === 'function' &&
|
||||
typeof performance.clearMeasures === 'function';
|
||||
|
||||
const shouldMark = function(debugID) {
|
||||
if (!isProfiling || !canUsePerformanceMeasure) {
|
||||
return false;
|
||||
}
|
||||
var element = ReactComponentTreeHook.getElement(debugID);
|
||||
if (element == null || typeof element !== 'object') {
|
||||
return false;
|
||||
}
|
||||
var isHostElement = typeof element.type === 'string';
|
||||
if (isHostElement) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
const markBegin = function(debugID, markType) {
|
||||
if (!shouldMark(debugID)) {
|
||||
return;
|
||||
}
|
||||
|
||||
isProfiling = true;
|
||||
flushHistory.length = 0;
|
||||
resetMeasurements();
|
||||
ReactDebugTool.addHook(ReactHostOperationHistoryHook);
|
||||
},
|
||||
endProfiling(): void {
|
||||
if (!isProfiling) {
|
||||
var markName = `${debugID}::${markType}`;
|
||||
lastMarkTimeStamp = performanceNow();
|
||||
performance.mark(markName);
|
||||
};
|
||||
|
||||
const markEnd = function(debugID, markType) {
|
||||
if (!shouldMark(debugID)) {
|
||||
return;
|
||||
}
|
||||
|
||||
isProfiling = false;
|
||||
resetMeasurements();
|
||||
ReactDebugTool.removeHook(ReactHostOperationHistoryHook);
|
||||
},
|
||||
getFlushHistory(): FlushHistory {
|
||||
return flushHistory;
|
||||
},
|
||||
onBeginFlush(): void {
|
||||
currentFlushNesting++;
|
||||
resetMeasurements();
|
||||
pauseCurrentLifeCycleTimer();
|
||||
emitEvent('onBeginFlush');
|
||||
},
|
||||
onEndFlush(): void {
|
||||
resetMeasurements();
|
||||
currentFlushNesting--;
|
||||
resumeCurrentLifeCycleTimer();
|
||||
emitEvent('onEndFlush');
|
||||
},
|
||||
onBeginLifeCycleTimer(debugID: DebugID, timerType: TimerType): void {
|
||||
checkDebugID(debugID);
|
||||
emitEvent('onBeginLifeCycleTimer', debugID, timerType);
|
||||
markBegin(debugID, timerType);
|
||||
beginLifeCycleTimer(debugID, timerType);
|
||||
},
|
||||
onEndLifeCycleTimer(debugID: DebugID, timerType: TimerType): void {
|
||||
checkDebugID(debugID);
|
||||
endLifeCycleTimer(debugID, timerType);
|
||||
markEnd(debugID, timerType);
|
||||
emitEvent('onEndLifeCycleTimer', debugID, timerType);
|
||||
},
|
||||
onBeginProcessingChildContext(): void {
|
||||
emitEvent('onBeginProcessingChildContext');
|
||||
},
|
||||
onEndProcessingChildContext(): void {
|
||||
emitEvent('onEndProcessingChildContext');
|
||||
},
|
||||
onHostOperation(operation: Operation) {
|
||||
checkDebugID(operation.instanceID);
|
||||
emitEvent('onHostOperation', operation);
|
||||
},
|
||||
onSetState(): void {
|
||||
emitEvent('onSetState');
|
||||
},
|
||||
onSetChildren(debugID: DebugID, childDebugIDs: Array<DebugID>) {
|
||||
checkDebugID(debugID);
|
||||
childDebugIDs.forEach(checkDebugID);
|
||||
emitEvent('onSetChildren', debugID, childDebugIDs);
|
||||
},
|
||||
onBeforeMountComponent(debugID: DebugID, element: ReactElement, parentDebugID: DebugID): void {
|
||||
checkDebugID(debugID);
|
||||
checkDebugID(parentDebugID, true);
|
||||
emitEvent('onBeforeMountComponent', debugID, element, parentDebugID);
|
||||
markBegin(debugID, 'mount');
|
||||
},
|
||||
onMountComponent(debugID: DebugID): void {
|
||||
checkDebugID(debugID);
|
||||
markEnd(debugID, 'mount');
|
||||
emitEvent('onMountComponent', debugID);
|
||||
},
|
||||
onBeforeUpdateComponent(debugID: DebugID, element: ReactElement): void {
|
||||
checkDebugID(debugID);
|
||||
emitEvent('onBeforeUpdateComponent', debugID, element);
|
||||
markBegin(debugID, 'update');
|
||||
},
|
||||
onUpdateComponent(debugID: DebugID): void {
|
||||
checkDebugID(debugID);
|
||||
markEnd(debugID, 'update');
|
||||
emitEvent('onUpdateComponent', debugID);
|
||||
},
|
||||
onBeforeUnmountComponent(debugID: DebugID): void {
|
||||
checkDebugID(debugID);
|
||||
emitEvent('onBeforeUnmountComponent', debugID);
|
||||
markBegin(debugID, 'unmount');
|
||||
},
|
||||
onUnmountComponent(debugID: DebugID): void {
|
||||
checkDebugID(debugID);
|
||||
markEnd(debugID, 'unmount');
|
||||
emitEvent('onUnmountComponent', debugID);
|
||||
},
|
||||
onTestEvent(): void {
|
||||
emitEvent('onTestEvent');
|
||||
},
|
||||
};
|
||||
var markName = `${debugID}::${markType}`;
|
||||
var displayName = ReactComponentTreeHook.getDisplayName(debugID) || 'Unknown';
|
||||
|
||||
ReactDebugTool.addHook(ReactInvalidSetStateWarningHook);
|
||||
ReactDebugTool.addHook(ReactComponentTreeHook);
|
||||
var url = (ExecutionEnvironment.canUseDOM && window.location.href) || '';
|
||||
if ((/[?&]react_perf\b/).test(url)) {
|
||||
ReactDebugTool.beginProfiling();
|
||||
// Chrome has an issue of dropping markers recorded too fast:
|
||||
// https://bugs.chromium.org/p/chromium/issues/detail?id=640652
|
||||
// To work around this, we will not report very small measurements.
|
||||
// I determined the magic number by tweaking it back and forth.
|
||||
// 0.05ms was enough to prevent the issue, but I set it to 0.1ms to be safe.
|
||||
// When the bug is fixed, we can `measure()` unconditionally if we want to.
|
||||
var timeStamp = performanceNow();
|
||||
if (timeStamp - lastMarkTimeStamp > 0.1) {
|
||||
var measurementName = `${displayName} [${markType}]`;
|
||||
performance.measure(measurementName, markName);
|
||||
}
|
||||
|
||||
performance.clearMarks(markName);
|
||||
performance.clearMeasures(measurementName);
|
||||
};
|
||||
|
||||
ReactDebugTool = {
|
||||
addHook(hook: Hook): void {
|
||||
hooks.push(hook);
|
||||
},
|
||||
removeHook(hook: Hook): void {
|
||||
for (var i = 0; i < hooks.length; i++) {
|
||||
if (hooks[i] === hook) {
|
||||
hooks.splice(i, 1);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
},
|
||||
isProfiling(): boolean {
|
||||
return isProfiling;
|
||||
},
|
||||
beginProfiling(): void {
|
||||
if (isProfiling) {
|
||||
return;
|
||||
}
|
||||
|
||||
isProfiling = true;
|
||||
flushHistory.length = 0;
|
||||
resetMeasurements();
|
||||
ReactDebugTool.addHook(ReactHostOperationHistoryHook);
|
||||
},
|
||||
endProfiling(): void {
|
||||
if (!isProfiling) {
|
||||
return;
|
||||
}
|
||||
|
||||
isProfiling = false;
|
||||
resetMeasurements();
|
||||
ReactDebugTool.removeHook(ReactHostOperationHistoryHook);
|
||||
},
|
||||
getFlushHistory(): FlushHistory {
|
||||
return flushHistory;
|
||||
},
|
||||
onBeginFlush(): void {
|
||||
currentFlushNesting++;
|
||||
resetMeasurements();
|
||||
pauseCurrentLifeCycleTimer();
|
||||
emitEvent('onBeginFlush');
|
||||
},
|
||||
onEndFlush(): void {
|
||||
resetMeasurements();
|
||||
currentFlushNesting--;
|
||||
resumeCurrentLifeCycleTimer();
|
||||
emitEvent('onEndFlush');
|
||||
},
|
||||
onBeginLifeCycleTimer(debugID: DebugID, timerType: TimerType): void {
|
||||
checkDebugID(debugID);
|
||||
emitEvent('onBeginLifeCycleTimer', debugID, timerType);
|
||||
markBegin(debugID, timerType);
|
||||
beginLifeCycleTimer(debugID, timerType);
|
||||
},
|
||||
onEndLifeCycleTimer(debugID: DebugID, timerType: TimerType): void {
|
||||
checkDebugID(debugID);
|
||||
endLifeCycleTimer(debugID, timerType);
|
||||
markEnd(debugID, timerType);
|
||||
emitEvent('onEndLifeCycleTimer', debugID, timerType);
|
||||
},
|
||||
onBeginProcessingChildContext(): void {
|
||||
emitEvent('onBeginProcessingChildContext');
|
||||
},
|
||||
onEndProcessingChildContext(): void {
|
||||
emitEvent('onEndProcessingChildContext');
|
||||
},
|
||||
onHostOperation(operation: Operation) {
|
||||
checkDebugID(operation.instanceID);
|
||||
emitEvent('onHostOperation', operation);
|
||||
},
|
||||
onSetState(): void {
|
||||
emitEvent('onSetState');
|
||||
},
|
||||
onSetChildren(debugID: DebugID, childDebugIDs: Array<DebugID>) {
|
||||
checkDebugID(debugID);
|
||||
childDebugIDs.forEach(checkDebugID);
|
||||
emitEvent('onSetChildren', debugID, childDebugIDs);
|
||||
},
|
||||
onBeforeMountComponent(debugID: DebugID, element: ReactElement, parentDebugID: DebugID): void {
|
||||
checkDebugID(debugID);
|
||||
checkDebugID(parentDebugID, true);
|
||||
emitEvent('onBeforeMountComponent', debugID, element, parentDebugID);
|
||||
markBegin(debugID, 'mount');
|
||||
},
|
||||
onMountComponent(debugID: DebugID): void {
|
||||
checkDebugID(debugID);
|
||||
markEnd(debugID, 'mount');
|
||||
emitEvent('onMountComponent', debugID);
|
||||
},
|
||||
onBeforeUpdateComponent(debugID: DebugID, element: ReactElement): void {
|
||||
checkDebugID(debugID);
|
||||
emitEvent('onBeforeUpdateComponent', debugID, element);
|
||||
markBegin(debugID, 'update');
|
||||
},
|
||||
onUpdateComponent(debugID: DebugID): void {
|
||||
checkDebugID(debugID);
|
||||
markEnd(debugID, 'update');
|
||||
emitEvent('onUpdateComponent', debugID);
|
||||
},
|
||||
onBeforeUnmountComponent(debugID: DebugID): void {
|
||||
checkDebugID(debugID);
|
||||
emitEvent('onBeforeUnmountComponent', debugID);
|
||||
markBegin(debugID, 'unmount');
|
||||
},
|
||||
onUnmountComponent(debugID: DebugID): void {
|
||||
checkDebugID(debugID);
|
||||
markEnd(debugID, 'unmount');
|
||||
emitEvent('onUnmountComponent', debugID);
|
||||
},
|
||||
onTestEvent(): void {
|
||||
emitEvent('onTestEvent');
|
||||
},
|
||||
};
|
||||
|
||||
ReactDebugTool.addHook(ReactInvalidSetStateWarningHook);
|
||||
ReactDebugTool.addHook(ReactComponentTreeHook);
|
||||
var url = (ExecutionEnvironment.canUseDOM && window.location.href) || '';
|
||||
if ((/[?&]react_perf\b/).test(url)) {
|
||||
ReactDebugTool.beginProfiling();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ReactDebugTool;
|
||||
|
||||
@@ -26,25 +26,30 @@ export type Operation = {instanceID: DebugID} & (
|
||||
{type: 'remove attribute', payload: string}
|
||||
);
|
||||
|
||||
var history: Array<Operation> = [];
|
||||
// Trust the developer to only use this with a __DEV__ check
|
||||
var ReactHostOperationHistoryHook = ((null: any): typeof ReactHostOperationHistoryHook);
|
||||
|
||||
var ReactHostOperationHistoryHook = {
|
||||
onHostOperation(operation: Operation) {
|
||||
history.push(operation);
|
||||
},
|
||||
if (__DEV__) {
|
||||
var history: Array<Operation> = [];
|
||||
|
||||
clearHistory(): void {
|
||||
if (ReactHostOperationHistoryHook._preventClearing) {
|
||||
// Should only be used for tests.
|
||||
return;
|
||||
}
|
||||
ReactHostOperationHistoryHook = {
|
||||
onHostOperation(operation: Operation) {
|
||||
history.push(operation);
|
||||
},
|
||||
|
||||
history = [];
|
||||
},
|
||||
clearHistory(): void {
|
||||
if (ReactHostOperationHistoryHook._preventClearing) {
|
||||
// Should only be used for tests.
|
||||
return;
|
||||
}
|
||||
|
||||
getHistory(): Array<Operation> {
|
||||
return history;
|
||||
},
|
||||
};
|
||||
history = [];
|
||||
},
|
||||
|
||||
getHistory(): Array<Operation> {
|
||||
return history;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = ReactHostOperationHistoryHook;
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
var warning = require('warning');
|
||||
|
||||
var ReactInvalidSetStateWarningHook = {};
|
||||
|
||||
if (__DEV__) {
|
||||
var processingChildContext = false;
|
||||
|
||||
@@ -23,18 +25,18 @@ if (__DEV__) {
|
||||
'setState(...): Cannot call setState() inside getChildContext()'
|
||||
);
|
||||
};
|
||||
|
||||
ReactInvalidSetStateWarningHook = {
|
||||
onBeginProcessingChildContext(): void {
|
||||
processingChildContext = true;
|
||||
},
|
||||
onEndProcessingChildContext(): void {
|
||||
processingChildContext = false;
|
||||
},
|
||||
onSetState(): void {
|
||||
warnInvalidSetState();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
var ReactInvalidSetStateWarningHook = {
|
||||
onBeginProcessingChildContext(): void {
|
||||
processingChildContext = true;
|
||||
},
|
||||
onEndProcessingChildContext(): void {
|
||||
processingChildContext = false;
|
||||
},
|
||||
onSetState(): void {
|
||||
warnInvalidSetState();
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = ReactInvalidSetStateWarningHook;
|
||||
|
||||
Reference in New Issue
Block a user