aboutsummaryrefslogtreecommitdiff
path: root/node_modules/react-dom/lib/ReactPerf.js
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2017-05-03 15:35:00 +0200
committerFlorian Dold <florian.dold@gmail.com>2017-05-03 15:35:00 +0200
commitde98e0b232509d5f40c135d540a70e415272ff85 (patch)
treea79222a5b58484ab3b80d18efcaaa7ccc4769b33 /node_modules/react-dom/lib/ReactPerf.js
parente0c9d480a73fa629c1e4a47d3e721f1d2d345406 (diff)
downloadwallet-core-de98e0b232509d5f40c135d540a70e415272ff85.tar.xz
node_modules
Diffstat (limited to 'node_modules/react-dom/lib/ReactPerf.js')
-rw-r--r--node_modules/react-dom/lib/ReactPerf.js500
1 files changed, 500 insertions, 0 deletions
diff --git a/node_modules/react-dom/lib/ReactPerf.js b/node_modules/react-dom/lib/ReactPerf.js
new file mode 100644
index 000000000..a7e1201bc
--- /dev/null
+++ b/node_modules/react-dom/lib/ReactPerf.js
@@ -0,0 +1,500 @@
+/**
+ * Copyright 2016-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ *
+ *
+ */
+
+'use strict';
+
+var _assign = require('object-assign');
+
+var _extends = _assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
+
+var ReactDebugTool = require('./ReactDebugTool');
+var warning = require('fbjs/lib/warning');
+var alreadyWarned = false;
+
+function roundFloat(val) {
+ var base = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2;
+
+ var n = Math.pow(10, base);
+ return Math.floor(val * n) / n;
+}
+
+// Flow type definition of console.table is too strict right now, see
+// https://github.com/facebook/flow/pull/2353 for updates
+function consoleTable(table) {
+ console.table(table);
+}
+
+function warnInProduction() {
+ if (alreadyWarned) {
+ return;
+ }
+ alreadyWarned = true;
+ if (typeof console !== 'undefined') {
+ console.error('ReactPerf is not supported in the production builds of React. ' + 'To collect measurements, please use the development build of React instead.');
+ }
+}
+
+function getLastMeasurements() {
+ if (!(process.env.NODE_ENV !== 'production')) {
+ warnInProduction();
+ return [];
+ }
+
+ return ReactDebugTool.getFlushHistory();
+}
+
+function getExclusive() {
+ var flushHistory = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getLastMeasurements();
+
+ if (!(process.env.NODE_ENV !== 'production')) {
+ warnInProduction();
+ return [];
+ }
+
+ var aggregatedStats = {};
+ var affectedIDs = {};
+
+ function updateAggregatedStats(treeSnapshot, instanceID, timerType, applyUpdate) {
+ var displayName = treeSnapshot[instanceID].displayName;
+
+ var key = displayName;
+ var stats = aggregatedStats[key];
+ if (!stats) {
+ affectedIDs[key] = {};
+ stats = aggregatedStats[key] = {
+ key: key,
+ instanceCount: 0,
+ counts: {},
+ durations: {},
+ totalDuration: 0
+ };
+ }
+ if (!stats.durations[timerType]) {
+ stats.durations[timerType] = 0;
+ }
+ if (!stats.counts[timerType]) {
+ stats.counts[timerType] = 0;
+ }
+ affectedIDs[key][instanceID] = true;
+ applyUpdate(stats);
+ }
+
+ flushHistory.forEach(function (flush) {
+ var measurements = flush.measurements,
+ treeSnapshot = flush.treeSnapshot;
+
+ measurements.forEach(function (measurement) {
+ var duration = measurement.duration,
+ instanceID = measurement.instanceID,
+ timerType = measurement.timerType;
+
+ updateAggregatedStats(treeSnapshot, instanceID, timerType, function (stats) {
+ stats.totalDuration += duration;
+ stats.durations[timerType] += duration;
+ stats.counts[timerType]++;
+ });
+ });
+ });
+
+ return Object.keys(aggregatedStats).map(function (key) {
+ return _extends({}, aggregatedStats[key], {
+ instanceCount: Object.keys(affectedIDs[key]).length
+ });
+ }).sort(function (a, b) {
+ return b.totalDuration - a.totalDuration;
+ });
+}
+
+function getInclusive() {
+ var flushHistory = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getLastMeasurements();
+
+ if (!(process.env.NODE_ENV !== 'production')) {
+ warnInProduction();
+ return [];
+ }
+
+ var aggregatedStats = {};
+ var affectedIDs = {};
+
+ function updateAggregatedStats(treeSnapshot, instanceID, applyUpdate) {
+ var _treeSnapshot$instanc = treeSnapshot[instanceID],
+ displayName = _treeSnapshot$instanc.displayName,
+ ownerID = _treeSnapshot$instanc.ownerID;
+
+ var owner = treeSnapshot[ownerID];
+ var key = (owner ? owner.displayName + ' > ' : '') + displayName;
+ var stats = aggregatedStats[key];
+ if (!stats) {
+ affectedIDs[key] = {};
+ stats = aggregatedStats[key] = {
+ key: key,
+ instanceCount: 0,
+ inclusiveRenderDuration: 0,
+ renderCount: 0
+ };
+ }
+ affectedIDs[key][instanceID] = true;
+ applyUpdate(stats);
+ }
+
+ var isCompositeByID = {};
+ flushHistory.forEach(function (flush) {
+ var measurements = flush.measurements;
+
+ measurements.forEach(function (measurement) {
+ var instanceID = measurement.instanceID,
+ timerType = measurement.timerType;
+
+ if (timerType !== 'render') {
+ return;
+ }
+ isCompositeByID[instanceID] = true;
+ });
+ });
+
+ flushHistory.forEach(function (flush) {
+ var measurements = flush.measurements,
+ treeSnapshot = flush.treeSnapshot;
+
+ measurements.forEach(function (measurement) {
+ var duration = measurement.duration,
+ instanceID = measurement.instanceID,
+ timerType = measurement.timerType;
+
+ if (timerType !== 'render') {
+ return;
+ }
+ updateAggregatedStats(treeSnapshot, instanceID, function (stats) {
+ stats.renderCount++;
+ });
+ var nextParentID = instanceID;
+ while (nextParentID) {
+ // As we traverse parents, only count inclusive time towards composites.
+ // We know something is a composite if its render() was called.
+ if (isCompositeByID[nextParentID]) {
+ updateAggregatedStats(treeSnapshot, nextParentID, function (stats) {
+ stats.inclusiveRenderDuration += duration;
+ });
+ }
+ nextParentID = treeSnapshot[nextParentID].parentID;
+ }
+ });
+ });
+
+ return Object.keys(aggregatedStats).map(function (key) {
+ return _extends({}, aggregatedStats[key], {
+ instanceCount: Object.keys(affectedIDs[key]).length
+ });
+ }).sort(function (a, b) {
+ return b.inclusiveRenderDuration - a.inclusiveRenderDuration;
+ });
+}
+
+function getWasted() {
+ var flushHistory = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getLastMeasurements();
+
+ if (!(process.env.NODE_ENV !== 'production')) {
+ warnInProduction();
+ return [];
+ }
+
+ var aggregatedStats = {};
+ var affectedIDs = {};
+
+ function updateAggregatedStats(treeSnapshot, instanceID, applyUpdate) {
+ var _treeSnapshot$instanc2 = treeSnapshot[instanceID],
+ displayName = _treeSnapshot$instanc2.displayName,
+ ownerID = _treeSnapshot$instanc2.ownerID;
+
+ var owner = treeSnapshot[ownerID];
+ var key = (owner ? owner.displayName + ' > ' : '') + displayName;
+ var stats = aggregatedStats[key];
+ if (!stats) {
+ affectedIDs[key] = {};
+ stats = aggregatedStats[key] = {
+ key: key,
+ instanceCount: 0,
+ inclusiveRenderDuration: 0,
+ renderCount: 0
+ };
+ }
+ affectedIDs[key][instanceID] = true;
+ applyUpdate(stats);
+ }
+
+ flushHistory.forEach(function (flush) {
+ var measurements = flush.measurements,
+ treeSnapshot = flush.treeSnapshot,
+ operations = flush.operations;
+
+ var isDefinitelyNotWastedByID = {};
+
+ // Find host components associated with an operation in this batch.
+ // Mark all components in their parent tree as definitely not wasted.
+ operations.forEach(function (operation) {
+ var instanceID = operation.instanceID;
+
+ var nextParentID = instanceID;
+ while (nextParentID) {
+ isDefinitelyNotWastedByID[nextParentID] = true;
+ nextParentID = treeSnapshot[nextParentID].parentID;
+ }
+ });
+
+ // Find composite components that rendered in this batch.
+ // These are potential candidates for being wasted renders.
+ var renderedCompositeIDs = {};
+ measurements.forEach(function (measurement) {
+ var instanceID = measurement.instanceID,
+ timerType = measurement.timerType;
+
+ if (timerType !== 'render') {
+ return;
+ }
+ renderedCompositeIDs[instanceID] = true;
+ });
+
+ measurements.forEach(function (measurement) {
+ var duration = measurement.duration,
+ instanceID = measurement.instanceID,
+ timerType = measurement.timerType;
+
+ if (timerType !== 'render') {
+ return;
+ }
+
+ // If there was a DOM update below this component, or it has just been
+ // mounted, its render() is not considered wasted.
+ var updateCount = treeSnapshot[instanceID].updateCount;
+
+ if (isDefinitelyNotWastedByID[instanceID] || updateCount === 0) {
+ return;
+ }
+
+ // We consider this render() wasted.
+ updateAggregatedStats(treeSnapshot, instanceID, function (stats) {
+ stats.renderCount++;
+ });
+
+ var nextParentID = instanceID;
+ while (nextParentID) {
+ // Any parents rendered during this batch are considered wasted
+ // unless we previously marked them as dirty.
+ var isWasted = renderedCompositeIDs[nextParentID] && !isDefinitelyNotWastedByID[nextParentID];
+ if (isWasted) {
+ updateAggregatedStats(treeSnapshot, nextParentID, function (stats) {
+ stats.inclusiveRenderDuration += duration;
+ });
+ }
+ nextParentID = treeSnapshot[nextParentID].parentID;
+ }
+ });
+ });
+
+ return Object.keys(aggregatedStats).map(function (key) {
+ return _extends({}, aggregatedStats[key], {
+ instanceCount: Object.keys(affectedIDs[key]).length
+ });
+ }).sort(function (a, b) {
+ return b.inclusiveRenderDuration - a.inclusiveRenderDuration;
+ });
+}
+
+function getOperations() {
+ var flushHistory = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getLastMeasurements();
+
+ if (!(process.env.NODE_ENV !== 'production')) {
+ warnInProduction();
+ return [];
+ }
+
+ var stats = [];
+ flushHistory.forEach(function (flush, flushIndex) {
+ var operations = flush.operations,
+ treeSnapshot = flush.treeSnapshot;
+
+ operations.forEach(function (operation) {
+ var instanceID = operation.instanceID,
+ type = operation.type,
+ payload = operation.payload;
+ var _treeSnapshot$instanc3 = treeSnapshot[instanceID],
+ displayName = _treeSnapshot$instanc3.displayName,
+ ownerID = _treeSnapshot$instanc3.ownerID;
+
+ var owner = treeSnapshot[ownerID];
+ var key = (owner ? owner.displayName + ' > ' : '') + displayName;
+
+ stats.push({
+ flushIndex: flushIndex,
+ instanceID: instanceID,
+ key: key,
+ type: type,
+ ownerID: ownerID,
+ payload: payload
+ });
+ });
+ });
+ return stats;
+}
+
+function printExclusive(flushHistory) {
+ if (!(process.env.NODE_ENV !== 'production')) {
+ warnInProduction();
+ return;
+ }
+
+ var stats = getExclusive(flushHistory);
+ var table = stats.map(function (item) {
+ var key = item.key,
+ instanceCount = item.instanceCount,
+ totalDuration = item.totalDuration;
+
+ var renderCount = item.counts.render || 0;
+ var renderDuration = item.durations.render || 0;
+ return {
+ 'Component': key,
+ 'Total time (ms)': roundFloat(totalDuration),
+ 'Instance count': instanceCount,
+ 'Total render time (ms)': roundFloat(renderDuration),
+ 'Average render time (ms)': renderCount ? roundFloat(renderDuration / renderCount) : undefined,
+ 'Render count': renderCount,
+ 'Total lifecycle time (ms)': roundFloat(totalDuration - renderDuration)
+ };
+ });
+ consoleTable(table);
+}
+
+function printInclusive(flushHistory) {
+ if (!(process.env.NODE_ENV !== 'production')) {
+ warnInProduction();
+ return;
+ }
+
+ var stats = getInclusive(flushHistory);
+ var table = stats.map(function (item) {
+ var key = item.key,
+ instanceCount = item.instanceCount,
+ inclusiveRenderDuration = item.inclusiveRenderDuration,
+ renderCount = item.renderCount;
+
+ return {
+ 'Owner > Component': key,
+ 'Inclusive render time (ms)': roundFloat(inclusiveRenderDuration),
+ 'Instance count': instanceCount,
+ 'Render count': renderCount
+ };
+ });
+ consoleTable(table);
+}
+
+function printWasted(flushHistory) {
+ if (!(process.env.NODE_ENV !== 'production')) {
+ warnInProduction();
+ return;
+ }
+
+ var stats = getWasted(flushHistory);
+ var table = stats.map(function (item) {
+ var key = item.key,
+ instanceCount = item.instanceCount,
+ inclusiveRenderDuration = item.inclusiveRenderDuration,
+ renderCount = item.renderCount;
+
+ return {
+ 'Owner > Component': key,
+ 'Inclusive wasted time (ms)': roundFloat(inclusiveRenderDuration),
+ 'Instance count': instanceCount,
+ 'Render count': renderCount
+ };
+ });
+ consoleTable(table);
+}
+
+function printOperations(flushHistory) {
+ if (!(process.env.NODE_ENV !== 'production')) {
+ warnInProduction();
+ return;
+ }
+
+ var stats = getOperations(flushHistory);
+ var table = stats.map(function (stat) {
+ return {
+ 'Owner > Node': stat.key,
+ 'Operation': stat.type,
+ 'Payload': typeof stat.payload === 'object' ? JSON.stringify(stat.payload) : stat.payload,
+ 'Flush index': stat.flushIndex,
+ 'Owner Component ID': stat.ownerID,
+ 'DOM Component ID': stat.instanceID
+ };
+ });
+ consoleTable(table);
+}
+
+var warnedAboutPrintDOM = false;
+function printDOM(measurements) {
+ process.env.NODE_ENV !== 'production' ? warning(warnedAboutPrintDOM, '`ReactPerf.printDOM(...)` is deprecated. Use ' + '`ReactPerf.printOperations(...)` instead.') : void 0;
+ warnedAboutPrintDOM = true;
+ return printOperations(measurements);
+}
+
+var warnedAboutGetMeasurementsSummaryMap = false;
+function getMeasurementsSummaryMap(measurements) {
+ process.env.NODE_ENV !== 'production' ? warning(warnedAboutGetMeasurementsSummaryMap, '`ReactPerf.getMeasurementsSummaryMap(...)` is deprecated. Use ' + '`ReactPerf.getWasted(...)` instead.') : void 0;
+ warnedAboutGetMeasurementsSummaryMap = true;
+ return getWasted(measurements);
+}
+
+function start() {
+ if (!(process.env.NODE_ENV !== 'production')) {
+ warnInProduction();
+ return;
+ }
+
+ ReactDebugTool.beginProfiling();
+}
+
+function stop() {
+ if (!(process.env.NODE_ENV !== 'production')) {
+ warnInProduction();
+ return;
+ }
+
+ ReactDebugTool.endProfiling();
+}
+
+function isRunning() {
+ if (!(process.env.NODE_ENV !== 'production')) {
+ warnInProduction();
+ return false;
+ }
+
+ return ReactDebugTool.isProfiling();
+}
+
+var ReactPerfAnalysis = {
+ getLastMeasurements: getLastMeasurements,
+ getExclusive: getExclusive,
+ getInclusive: getInclusive,
+ getWasted: getWasted,
+ getOperations: getOperations,
+ printExclusive: printExclusive,
+ printInclusive: printInclusive,
+ printWasted: printWasted,
+ printOperations: printOperations,
+ start: start,
+ stop: stop,
+ isRunning: isRunning,
+ // Deprecated:
+ printDOM: printDOM,
+ getMeasurementsSummaryMap: getMeasurementsSummaryMap
+};
+
+module.exports = ReactPerfAnalysis; \ No newline at end of file