performance_timing_tracker/PerformanceTimingTracker.js

'use strict';

/**
  Tracks for the local performance metrics of the user's browser
  Uses the PerformanceTimingApi, along with getter / setter to add our own values
  to this mix of stats
  @memberof module:Viki
**/
class PerformanceTimingTracker {

  /**
    Setup the local reference to the performance api as well as setup a local
    datastore for storing any custom metrics
    @constructor
  **/
  constructor() {
    const performance = window.performance || window.mozPerformance ||
    window.msPerformance || window.webkitPerformance || {};
    this.performanceTimingApi = performance.timing || {};
    this.recordStore = {};
  }

  /**
    Save some custom metric value with an identifying key
    @param {String} key Identifier corresponding to the property to be stored
    @param {Any} value Any value type that can be stored as part of a custom metric
  **/
  set(key, value) {
    this.recordStore[key] = value;
  }

  /**
    Retrive some metric value with an identifying key
    @param {String} key Identifier corresponding to the property that is stored
    @returns {Any|Null} The corresponding value to the requested key, or null if not found
  **/
  get(key) {
    let result;
    if (!this.isUndefined(this.recordStore[key])) {
      result = this.recordStore[key];
    } else if (!this.isUndefined(this.performanceTimingApi[key])) {
      result = this.performanceTimingApi[key];
    } else {
      result = null;
    }
    return result;
  }

  /**
    Verfies if some input value correspond to the type 'number'
    @returns {Boolean}
  **/
  isNumerical(value) {
    return typeof(value) === 'number';
  }

  /**
    Verfies if some input value correspond to the type 'undefined'
    @returns {Boolean}
  **/
  isUndefined(value) {
    return typeof(value) === 'undefined';
  }

  /**
    Save some custom metric value with an identifying key
    @param {String} firstKey Identifier corresponding to the primary value to be compared
    @param {String} secondKey Identifier corresponding to the secondary value to be compared
    @param {String} newKey Identifier for saving the difference in retrieved values
  **/
  setDifferenceAsValue(firstKey, secondKey, newKey) {
    const firstValue = this.get(firstKey);
    const secondValue = this.get(secondKey);
    if (this.isNumerical(firstValue) && this.isNumerical(secondValue)) {
      this.set(newKey, firstValue - secondValue);
    }
  }

  /**
    Flatten the performance api metrics and custom metrics and return the
    combined object as a JSON object
    @returns {JSON}
  **/
  extractMetrics() {
    const performanceTimingApiJson = this.performanceTimingApi.toJSON ?
    this.performanceTimingApi.toJSON() : this.performanceTimingApi;
    return Object.assign({}, performanceTimingApiJson, this.recordStore);
  }
}

module.exports = PerformanceTimingTracker;