appmetrics.js
appmetrics.js copied to clipboard
ES6 modules
It would be great to support it. For now, the best way I see to use this module is by copy-pasting the content into one of my files.
Does import Metric from 'appmetrics.js'
not work? I guess I need an export default
?
I have noticed several things to do to make it work:
- Export the Metric class:
export default Metric;
- Point the main section of the
package.json
toward the right entry point. Right now, it's pointing toward"main": "./src/appmetrics.js"
. But it's very common to ignore thenode_modules
when using babel.
Here is the version I'm using:
// @flow weak
import warning from 'warning'; // Allow to remove the assertion code from production
const start = new WeakMap();
const end = new WeakMap();
// Not sure why weren't private method.
/**
* True if the the browser supports the Navigation Timing API.
* @type {boolean}
*/
function supportsPerfNow() {
return window.performance && window.performance.now;
}
/**
* True if the the browser supports the User Timing API.
* @type {boolean}
*/
function supportsPerfMark() {
return window.performance && window.performance.mark;
}
// Inspired by https://github.com/ebidel/appmetrics.js
class Metric {
/**
* Returns the duration of the timing metric or -1 if there a measurement has
* not been made.
* @type {number}
*/
get duration() {
let duration;
if (supportsPerfNow()) {
duration = end.get(this) - start.get(this);
}
// Use User Timing API results if available, otherwise return
// window.performance.now() fallback.
if (supportsPerfMark()) {
// Note: this assumes the user has made only one measurement for the given
// name. Return the first one found.
const entry = window.performance.getEntriesByName(this.name)[0];
if (entry && entry.entryType !== 'measure') {
duration = entry.duration;
}
}
return duration || -1;
}
name = '';
/**
* @param {string} name A name for the metric.
*/
constructor(name) {
warning(name, 'Please provide a metric name');
// Simplify it, I don't want to crash when the performance API is not supported.
this.name = name;
}
/**
* Call to begin a measurement.
* @return {Metric} Instance of this object.
*/
start() {
if (start.get(this)) {
warning(false, 'Recording already started.');
return this;
}
if (supportsPerfNow()) {
start.set(this, window.performance.now());
}
// Support: developer.mozilla.org/en-US/docs/Web/API/Performance/mark
if (supportsPerfMark()) {
window.performance.mark(`mark_${this.name}_start`);
}
return this;
}
/**
* Call to end a measurement.
* @return {Metric} Instance of this object.
*/
end() {
if (end.get(this)) {
warning(false, 'Recording already stopped.');
return this;
}
if (supportsPerfNow()) {
end.set(this, window.performance.now());
}
// Support: developer.mozilla.org/en-US/docs/Web/API/Performance/mark
if (supportsPerfMark()) {
const startMark = `mark_${this.name}_start`;
const endMark = `mark_${this.name}_end`;
window.performance.mark(endMark);
window.performance.measure(this.name, startMark, endMark);
}
return this;
}
// Remove sendToAnalytics as I'm using different API based on the platfrom : cordova / browser.
}
export default Metric;
I have been publishing that among other tools for my needs under browser-metrics.
Any interest in sending a pr?