Example #1
0
function resetMeasurements() {
  var previousStartTime = currentFlushStartTime;
  var previousMeasurements = currentFlushMeasurements || [];
  var previousOperations = ReactHostOperationHistoryDevtool.getHistory();

  if (currentFlushNesting === 0) {
    currentFlushStartTime = null;
    currentFlushMeasurements = null;
    clearHistory();
    return;
  }

  if (previousMeasurements.length || previousOperations.length) {
    var registeredIDs = ReactComponentTreeDevtool.getRegisteredIDs();
    flushHistory.push({
      duration: performanceNow() - previousStartTime,
      measurements: previousMeasurements || [],
      operations: previousOperations || [],
      treeSnapshot: getTreeSnapshot(registeredIDs),
    });
  }

  clearHistory();
  currentFlushStartTime = performanceNow();
  currentFlushMeasurements = [];
}
 constructor(props, context) {
   super(props, context);
   this.state = {
     ctorTimestamp: performanceNow(),
     timeToMount: 0,
   };
 }
Example #3
0
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 = null;
  currentTimerNestedFlushDuration = null;
  currentTimerDebugID = null;
  currentTimerType = null;
}
 constructor(props: mixed, context: mixed) {
   super(props, context);
   this.start = performanceNow();
   this.state = {
     stats: null,
   };
   (this: any)._onDone = this._onDone.bind(this);
 }
Example #5
0
function resumeCurrentLifeCycleTimer() {
  var {startTime, nestedFlushStartTime, debugID, timerType} = lifeCycleTimerStack.pop();
  var nestedFlushDuration = performanceNow() - nestedFlushStartTime;
  currentTimerStartTime = startTime;
  currentTimerNestedFlushDuration += nestedFlushDuration;
  currentTimerDebugID = debugID;
  currentTimerType = timerType;
}
Example #6
0
function markBegin(debugID, markType) {
  if (!shouldMark(debugID)) {
    return;
  }

  var markName = `${debugID}::${markType}`;
  lastMarkTimeStamp = performanceNow();
  performance.mark(markName);
}
Example #7
0
 constructor() {
   this._initTime = performanceNow();
   this._queryID = 0;
   this._subscription = Relay.Store.addNetworkSubscriber(
     request =>
       this.logRequest(createDebuggableFromRequest('Relay Query', request)),
     request =>
       this.logRequest(createDebuggableFromRequest('Relay Mutation', request))
   );
 }
Example #8
0
      return function(...args) {
        var timeBeforeFn = performanceNow();
        var fnReturn = func.apply(this, args);
        var timeAfterFn = performanceNow();

        /**
         * Hold onto arguments in a readable way: args[1] -> args.component.
         * args is also passed to the callback, so if you want to save an
         * argument in the log, do so in the callback.
         */
        var argsObject = {};
        for (var i = 0; i < args.length; i++) {
          argsObject[fnArgs[i]] = args[i];
        }

        var log = {
          index: ReactDefaultPerf.logs.length,
          fnName: fnName,
          objName: objName,
          timing: {
            before: timeBeforeFn,
            after: timeAfterFn,
            delta: timeAfterFn - timeBeforeFn
          }
        };

        ReactDefaultPerf.logs.push(log);

        /**
         * The callback gets:
         * - this (the component)
         * - the original method's arguments
         * - what the method returned
         * - the log object, and
         * - the wrapped method's info object.
         */
        var callback = _getCallback(objName, fnName);
        callback && callback(this, argsObject, fnReturn, log, info);

        log.timing.timeToLog = performanceNow() - timeAfterFn;

        return fnReturn;
      };
 const onSettled = (error, response) => {
   const time = (performanceNow() - this._initTime) / 1000;
   console.timeStamp(`← END: [${id}] ${type}: ${name}`);
   console.groupCollapsed(
     `%c[${id}] ${type}: ${name} @ ${time}s`,
     `color:${error ? 'red' : 'black'};`
   );
   console.timeEnd(timerName);
   logResult(error, response);
   console.groupEnd();
 };
 setTimeout(() => {
   const stats = {
     onDoneElapsed,
     totalWidgets,
     ...JSEventLoopWatchdog.getStats(),
     setTimeoutElapsed: performanceNow() - this.start,
   };
   stats.avgStall = stats.totalStallTime / stats.stallCount;
   this.setState({stats});
   console.log('onDone:', stats);
 }, 0);
Example #11
0
function resetMeasurements() {
  if (__DEV__) {
    if (!isProfiling || currentFlushNesting === 0) {
      currentFlushStartTime = null;
      currentFlushMeasurements = null;
      return;
    }

    var previousStartTime = currentFlushStartTime;
    var previousMeasurements = currentFlushMeasurements || [];
    var previousOperations = ReactNativeOperationHistoryDevtool.getHistory();

    if (previousMeasurements.length || previousOperations.length) {
      var registeredIDs = ReactComponentTreeDevtool.getRegisteredIDs();
      flushHistory.push({
        duration: performanceNow() - previousStartTime,
        measurements: previousMeasurements || [],
        operations: previousOperations || [],
        treeSnapshot: registeredIDs.reduce((tree, id) => {
          var ownerID = ReactComponentTreeDevtool.getOwnerID(id);
          var parentID = ReactComponentTreeDevtool.getParentID(id);
          tree[id] = {
            displayName: ReactComponentTreeDevtool.getDisplayName(id),
            text: ReactComponentTreeDevtool.getText(id),
            updateCount: ReactComponentTreeDevtool.getUpdateCount(id),
            childIDs: ReactComponentTreeDevtool.getChildIDs(id),
            // Text nodes don't have owners but this is close enough.
            ownerID: ownerID || ReactComponentTreeDevtool.getOwnerID(parentID),
            parentID,
          };
          return tree;
        }, {}),
      });
    }

    currentFlushStartTime = performanceNow();
    currentFlushMeasurements = [];
    ReactComponentTreeDevtool.purgeUnmountedComponents();
    ReactNativeOperationHistoryDevtool.clearHistory();
  }
}
Example #12
0
function pauseCurrentLifeCycleTimer() {
  var currentTimer = {
    startTime: currentTimerStartTime,
    nestedFlushStartTime: performanceNow(),
    debugID: currentTimerDebugID,
    timerType: currentTimerType,
  };
  lifeCycleTimerStack.push(currentTimer);
  currentTimerStartTime = null;
  currentTimerNestedFlushDuration = null;
  currentTimerDebugID = null;
  currentTimerType = null;
}
Example #13
0
 const queryCallback = (id: number, pendingQuery, error, results) => {
   const time = performanceNow() - initTime;
   const name = pendingQuery.getDebugName();
   console.timeStamp(`← END: Relay query ${id} ${name}`);
   console.groupCollapsed(
     `%cRelay query ${id} ${time / 1000} ${name}`,
     `color:${error ? 'red' : 'black'};`
   );
   console.timeEnd(id);
   const query = pendingQuery.getQueryString();
   console.debug(
     '%c%s\n',
     'font-size:10px; color:#333; font-family:mplus-2m-regular,menlo,' +
     'monospaced;',
     query
   );
   error && console.error(error);
   results && console.log(results);
   console.groupEnd();
 };
Example #14
0
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;
}
Example #15
0
  callTimer: function(timerID) {
    warning(timerID <= JSTimersExecution.GUID, 'Tried to call timer with ID ' + timerID + ' but no such timer exists');
    var timerIndex = JSTimersExecution.timerIDs.indexOf(timerID);
    // timerIndex of -1 means that no timer with that ID exists. There are
    // two situations when this happens, when a garbage timer ID was given
    // and when a previously existing timer was deleted before this callback
    // fired. In both cases we want to ignore the timer id, but in the former
    // case we warn as well.
    if (timerIndex === -1) {
      return;
    }
    var type = JSTimersExecution.types[timerIndex];
    var callback = JSTimersExecution.callbacks[timerIndex];

    // Clear the metadata
    if (type === JSTimersExecution.Type.setTimeout ||
        type === JSTimersExecution.Type.setImmediate ||
        type === JSTimersExecution.Type.requestAnimationFrame) {
      JSTimersExecution._clearIndex(timerIndex);
    }

    try {
      if (type === JSTimersExecution.Type.setTimeout ||
          type === JSTimersExecution.Type.setInterval ||
          type === JSTimersExecution.Type.setImmediate) {
        callback();
      } else if (type === JSTimersExecution.Type.requestAnimationFrame) {
        var currentTime = performanceNow();
        callback(currentTime);
      } else {
        console.error('Tried to call a callback with invalid type: ' + type);
        return;
      }
    } catch (e) {
      // Don't rethrow so that we can run every other timer.
      JSTimersExecution.errors = JSTimersExecution.errors || [];
      JSTimersExecution.errors.push(e);
    }
  },
Example #16
0
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);
}
Example #17
0
   emitEvent('onEndFlush');
 },
 onBeginLifeCycleTimer(debugID, timerType) {
   emitEvent('onBeginLifeCycleTimer', debugID, timerType);
   if (__DEV__) {
     if (isProfiling && currentFlushNesting > 0) {
       warning(
         !currentTimerType,
         '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'
       );
       currentTimerStartTime = performanceNow();
       currentTimerDebugID = debugID;
       currentTimerType = timerType;
     }
   }
 },
 onEndLifeCycleTimer(debugID, timerType) {
   if (__DEV__) {
     if (isProfiling && currentFlushNesting > 0) {
       warning(
         currentTimerType === timerType,
         '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',
Example #18
0
 * Copyright (c) 2013-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.
 *
 * @providesModule generateClientID
 * @typechecks
 */

'use strict';

const crc32 = require('crc32');
const performanceNow = require('performanceNow');

let _clientID = 1;
const _prefix = 'client:' + crc32('' + performanceNow());

/**
 * Generate a unique clientID for GraphQL data objects that do not already have
 * an ID or their ID = null
 *
 * @internal
 */
function generateClientID() {
  return _prefix + _clientID++;
}

module.exports = generateClientID;
function burnCPU(milliseconds) {
  const start = performanceNow();
  while (performanceNow() < (start + milliseconds)) {}
}
 componentDidMount() {
   const timeToMount = performanceNow() - this.state.ctorTimestamp;
   this.setState({timeToMount});
   totalWidgets++;
 }
Example #21
0
    return function(...args) {
      var totalTime;
      var rv;
      var start;

      if (fnName === '_renderNewRootComponent' ||
          fnName === 'flushBatchedUpdates') {
        // A "measurement" is a set of metrics recorded for each flush. We want
        // to group the metrics for a given flush together so we can look at the
        // components that rendered and the DOM operations that actually
        // happened to determine the amount of "wasted work" performed.
        ReactDefaultPerf._allMeasurements.push({
          exclusive: {},
          inclusive: {},
          render: {},
          counts: {},
          writes: {},
          displayNames: {},
          totalTime: 0
        });
        start = performanceNow();
        rv = func.apply(this, args);
        ReactDefaultPerf._allMeasurements[
          ReactDefaultPerf._allMeasurements.length - 1
        ].totalTime = performanceNow() - start;
        return rv;
      } else if (moduleName === 'ReactDOMIDOperations' ||
        moduleName === 'ReactComponentBrowserEnvironment') {
        start = performanceNow();
        rv = func.apply(this, args);
        totalTime = performanceNow() - start;

        if (fnName === '_mountImageIntoNode') {
          var mountID = ReactMount.getID(args[1]);
          ReactDefaultPerf._recordWrite(mountID, fnName, totalTime, args[0]);
        } else if (fnName === 'dangerouslyProcessChildrenUpdates') {
          // special format
          args[0].forEach(function(update) {
            var writeArgs = {};
            if (update.fromIndex !== null) {
              writeArgs.fromIndex = update.fromIndex;
            }
            if (update.toIndex !== null) {
              writeArgs.toIndex = update.toIndex;
            }
            if (update.textContent !== null) {
              writeArgs.textContent = update.textContent;
            }
            if (update.markupIndex !== null) {
              writeArgs.markup = args[1][update.markupIndex];
            }
            ReactDefaultPerf._recordWrite(
              update.parentID,
              update.type,
              totalTime,
              writeArgs
            );
          });
        } else {
          // basic format
          ReactDefaultPerf._recordWrite(
            args[0],
            fnName,
            totalTime,
            Array.prototype.slice.call(args, 1)
          );
        }
        return rv;
      } else if (moduleName === 'ReactCompositeComponent' && (
        fnName === 'mountComponent' ||
        fnName === 'updateComponent' || // TODO: receiveComponent()?
        fnName === '_renderValidatedComponent')) {

        var rootNodeID = fnName === 'mountComponent' ?
          args[0] :
          this._rootNodeID;
        var isRender = fnName === '_renderValidatedComponent';
        var isMount = fnName === 'mountComponent';

        var mountStack = ReactDefaultPerf._mountStack;
        var entry = ReactDefaultPerf._allMeasurements[
          ReactDefaultPerf._allMeasurements.length - 1
        ];

        if (isRender) {
          addValue(entry.counts, rootNodeID, 1);
        } else if (isMount) {
          mountStack.push(0);
        }

        start = performanceNow();
        rv = func.apply(this, args);
        totalTime = performanceNow() - start;

        if (isRender) {
          addValue(entry.render, rootNodeID, totalTime);
        } else if (isMount) {
          var subMountTime = mountStack.pop();
          mountStack[mountStack.length - 1] += totalTime;
          addValue(entry.exclusive, rootNodeID, totalTime - subMountTime);
          addValue(entry.inclusive, rootNodeID, totalTime);
        } else {
          addValue(entry.inclusive, rootNodeID, totalTime);
        }

        entry.displayNames[rootNodeID] = {
          current: typeof this._currentElement.type === 'string' ?
            this._currentElement.type :
            this.getName(),
          owner: this._currentElement._owner ?
            this._currentElement._owner.getName() :
            '<root>'
        };

        return rv;
      } else {
        return func.apply(this, args);
      }
    };
Example #22
0
 * @typechecks
 * @flow
 */

'use strict';

import type RelayMutationRequest from 'RelayMutationRequest';
const Relay = require('RelayPublic');
import type RelayQueryRequest from 'RelayQueryRequest';
import type {NetworkLayer} from 'RelayTypes';

const performanceNow = require('performanceNow');

const RelayNetworkDebug = {
  init(networkLayer: NetworkLayer): void {
    const initTime = performanceNow();

    const queryCallback = (id: number, pendingQuery, error, results) => {
      const time = performanceNow() - initTime;
      const name = pendingQuery.getDebugName();
      console.timeStamp(`← END: Relay query ${id} ${name}`);
      console.groupCollapsed(
        `%cRelay query ${id} ${time / 1000} ${name}`,
        `color:${error ? 'red' : 'black'};`
      );
      console.timeEnd(id);
      const query = pendingQuery.getQueryString();
      console.debug(
        '%c%s\n',
        'font-size:10px; color:#333; font-family:mplus-2m-regular,menlo,' +
        'monospaced;',