Source code

Revision control

Copy as Markdown

Other Tools

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
let usablePerfObj = window.performance;
export function _PerfService(options) {
// For testing, so that we can use a fake Window.performance object with
// known state.
if (options && options.performanceObj) {
this._perf = options.performanceObj;
} else {
this._perf = usablePerfObj;
}
}
_PerfService.prototype = {
/**
* Calls the underlying mark() method on the appropriate Window.performance
* object to add a mark with the given name to the appropriate performance
* timeline.
*
* @param {String} name the name to give the current mark
* @return {void}
*/
mark: function mark(str) {
this._perf.mark(str);
},
/**
* Calls the underlying getEntriesByName on the appropriate Window.performance
* object.
*
* @param {String} name
* @param {String} type eg "mark"
* @return {Array} Performance* objects
*/
getEntriesByName: function getEntriesByName(entryName, type) {
return this._perf.getEntriesByName(entryName, type);
},
/**
* The timeOrigin property from the appropriate performance object.
* Used to ensure that timestamps from the add-on code and the content code
* are comparable.
*
* @note If this is called from a context without a window
* (eg a JSM in chrome), it will return the timeOrigin of the XUL hidden
* window, which appears to be the first created window (and thus
* timeOrigin) in the browser. Note also, however, there is also a private
* hidden window, presumably for private browsing, which appears to be
* created dynamically later. Exactly how/when that shows up needs to be
* investigated.
*
* @return {Number} A double of milliseconds with a precision of 0.5us.
*/
get timeOrigin() {
return this._perf.timeOrigin;
},
/**
* Returns the "absolute" version of performance.now(), i.e. one that
* be comparable across both chrome and content.
*
* @return {Number}
*/
absNow: function absNow() {
return this.timeOrigin + this._perf.now();
},
/**
* This returns the absolute startTime from the most recent performance.mark()
* with the given name.
*
* @param {String} name the name to lookup the start time for
*
* @return {Number} the returned start time, as a DOMHighResTimeStamp
*
* @throws {Error} "No Marks with the name ..." if none are available
*
* @note Always surround calls to this by try/catch. Otherwise your code
* may fail when the `privacy.resistFingerprinting` pref is true. When
* this pref is set, all attempts to get marks will likely fail, which will
* cause this method to throw.
*
* for more info.
*/
getMostRecentAbsMarkStartByName(entryName) {
let entries = this.getEntriesByName(entryName, "mark");
if (!entries.length) {
throw new Error(`No marks with the name ${entryName}`);
}
let mostRecentEntry = entries[entries.length - 1];
return this._perf.timeOrigin + mostRecentEntry.startTime;
},
};
export const perfService = new _PerfService();