nanotiming
Advanced tools
Comparing version
50
index.js
var assert = require('assert') | ||
module.exports = Nanotiming | ||
var hasPerf = typeof window !== 'undefined' && | ||
window.performance && window.performance.mark | ||
function Nanotiming (name) { | ||
if (!(this instanceof Nanotiming)) return new Nanotiming(name) | ||
assert.equal(typeof name, 'string', 'Nanotiming: name should be type string') | ||
this._name = name | ||
this._enabled = typeof window !== 'undefined' && | ||
window.performance && window.performance.mark | ||
} | ||
module.exports = nanotiming | ||
Nanotiming.prototype.start = function (partial) { | ||
if (!this._enabled) return | ||
var name = partial ? this._name + '/' + partial : this._name | ||
var uuid = createUuid() | ||
window.performance.mark(name + '-start-' + uuid) | ||
return uuid | ||
} | ||
function nanotiming (name) { | ||
assert.equal(typeof name, 'string', 'nanotiming: name should be type string') | ||
Nanotiming.prototype.end = function (uuid, partial) { | ||
if (!this._enabled) return | ||
if (!hasPerf) return noop | ||
assert.equal(typeof uuid, 'string', 'Nanotiming.end: uuid should be type string') | ||
var name = partial ? this._name + '/' + partial : this._name | ||
var endName = name + '-end-' + uuid | ||
var uuid = (window.performance.now() * 100).toFixed() | ||
var startName = name + '-start-' + uuid | ||
window.performance.mark(endName) | ||
window.performance.mark(startName) | ||
ric(function () { | ||
window.performance.measure(name, startName, endName) | ||
window.performance.clearMarks(startName) | ||
window.performance.clearMarks(endName) | ||
}) | ||
} | ||
return function () { | ||
var endName = name + '-end-' + uuid | ||
window.performance.mark(endName) | ||
function createUuid () { | ||
return window.performance.now() % 9e6 | ||
ric(function () { | ||
var measureName = name + ' [' + uuid + ']' | ||
window.performance.measure(measureName, startName, endName) | ||
window.performance.clearMarks(startName) | ||
window.performance.clearMarks(endName) | ||
}) | ||
} | ||
} | ||
@@ -46,1 +34,3 @@ | ||
} | ||
function noop () {} |
@@ -5,3 +5,3 @@ { | ||
"repository": "yoshuawuyts/nanotiming", | ||
"version": "3.0.2", | ||
"version": "4.0.0", | ||
"scripts": { | ||
@@ -8,0 +8,0 @@ "deps": "dependency-check . && dependency-check . --extra --no-dev", |
@@ -11,39 +11,35 @@ # nanotiming [![stability][0]][1] | ||
var nanotiming = require('nanotiming') | ||
var timing = nanotiming('my-timing') | ||
timing.start('my-loop') | ||
var loopTiming = nanotiming('my-timing.my-loop') | ||
var i = 1000 | ||
while (--i) console.log(i) | ||
timing.end('my-loop') | ||
loopTiming() | ||
// Process marks when we have spare time available | ||
// Inspect timings when we have spare time available | ||
window.requestIdleCallback(function () { | ||
var name = 'my-timing/my-loop' | ||
var timings = window.performance.getEntriesByName(name) | ||
console.log(timings[timings.length - 1]) // log the last entry | ||
performance.clearMeasures(name) // be a good citizen and free up memory | ||
var timings = window.performance.getEntries() | ||
var timing = timings[timings.length - 1] | ||
console.log(timing.name, timing.duration) // log the last entry | ||
performance.clearMeasures(timing.name) // be a good citizen and free after use | ||
}) | ||
``` | ||
## Timing names | ||
Timings inside the view are appended with a unique UUID so they can be cleared | ||
individually. While there's no strict format for timing formats, we recommend | ||
using a format along these lines: | ||
```txt | ||
choo.render [12356778] | ||
choo.route('/') [13355671] | ||
choo.emit('log:debug') [13355675] | ||
``` | ||
## API | ||
### `timing = nanotiming([instanceName])` | ||
Create a new Nanotiming instance. Takes a name for the timing instance. | ||
### `endTiming = nanotiming(name)` | ||
Start a new timing. | ||
### `uuid = timing.start([methodName])` | ||
Start a timing. Takes a method name. The method name is concatenated to the | ||
instance name as `<instanceName>/<methodName>`. If no method name is passed, | ||
it'll fall back to only using the instance name. It's recommended that per | ||
instance to either always use method names, or never. | ||
### `endTiming()` | ||
Close the timing. Measuring the timing is done inside a `requestIdleCallback()` | ||
tick, so it might not be available immediately. | ||
Returns a `uuid` that should be passed to `timing.end()` so async timings work. | ||
### `timing.end(uuid, [methodName])` | ||
End a timing. The name here must be the same as `timing.start()`. If you want | ||
to do use this in async conditions make sure the name is unique, for example by | ||
appending a unique id to both start and end. The `performance.measure()` step | ||
is performed in a `requestIdleCallback()` tick, so make sure to process | ||
measures asynchronously, and preferably in later idle callbacks. | ||
Takes the uuid that is povided by `timing.start()` so async timings work. | ||
## License | ||
@@ -50,0 +46,0 @@ [MIT](https://tldrlegal.com/license/mit-license) |
4975
-15.36%26
-27.78%59
-6.35%