UNPKG

lag-monitor

Version:

A lightweight utility for monitoring JavaScript event loop lag in real-time

12 lines (11 loc) 3.92 kB
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).EventLoopLagMonitor={})}(this,(function(t){"use strict";class e{constructor(t){this.capacity=t,this.index=0,this.filled=0,this.buffer=new Array(t)}push(t){this.buffer[this.index]=t,this.index=(this.index+1)%this.capacity,this.filled=Math.min(this.filled+1,this.capacity)}get latest(){if(0===this.filled)return;const t=(this.index-1+this.capacity)%this.capacity;return this.buffer[t]}toArray(){return this.filled<this.capacity?this.buffer.slice(0,this.filled):[...this.buffer.slice(this.index),...this.buffer.slice(0,this.index)]}get length(){return this.filled}clear(){this.index=0,this.filled=0}}const i={lagType:"setTimeout",sampleRate:100,sampleCount:10,callback:void 0,autoStart:!0};class s{constructor(t=i){this.isActive=!1,this.timerId=null,this.lastTimestamp=void 0,this.options=Object.assign({},i,t),this.userMetrics=t.userMetrics||{},this.lagSamples=new e(this.options.sampleCount||i.sampleCount),this.options.autoStart&&this.start()}get latest(){return this.lagSamples.latest||0}get average(){return this.lagSamples.toArray().reduce(((t,e)=>t+e),0)/this.lagSamples.length}get min(){return Math.min(...this.lagSamples.toArray())}get max(){return Math.max(...this.lagSamples.toArray())}scheduleNext(t,e){if(this.clearTimer(),"requestAnimationFrame"===this.options.lagType){if("undefined"!=typeof requestAnimationFrame)return requestAnimationFrame(t);throw new Error("requestAnimationFrame is not supported in this environment. Use setTimeout or setInterval instead.")}return"setInterval"===this.options.lagType?setInterval(t,e):setTimeout(t,e)}tick(){if(!this.isActive)return;const t=performance.now(),e=this.lastTimestamp?Math.max(0,t-this.lastTimestamp-(this.options.sampleRate||i.sampleRate)):0;if(this.lastTimestamp=t,this.lagSamples.push(e),this.options.callback)try{this.options.callback(e,this.snapshot())}catch(t){console.warn("Lag monitor callback error:",t)}this.clearTimer(),this.timerId=this.scheduleNext((()=>this.tick()),this.options.sampleRate||i.sampleRate)}clearTimer(){this.timerId&&("requestAnimationFrame"===this.options.lagType?cancelAnimationFrame(this.timerId):"setInterval"===this.options.lagType?clearInterval(this.timerId):clearTimeout(this.timerId),this.timerId=null)}getMetricValue(t){const e=this.userMetrics[t];if(e)try{return e(this.lagSamples.toArray())}catch(e){return void console.warn(`Error computing user metric '${t}':`,e)}switch(t){case"latest":return this.latest;case"average":return this.average;case"min":return this.min;case"max":return this.max;case"samples":return this.lagSamples.length}}getAvailableMetrics(){return["latest","average","min","max","samples",...Object.keys(this.userMetrics)]}snapshot(t){if(t){const e=this.getMetricValue(t);return{[t]:e}}const e={};return this.getAvailableMetrics().forEach((t=>{e[t]=this.getMetricValue(t)})),e}start(){this.isActive?console.warn("Lag monitor is already running"):(this.isActive=!0,this.lastTimestamp=performance.now(),this.timerId=this.scheduleNext((()=>this.tick()),this.options.sampleRate||i.sampleRate))}stop(){this.isActive?(this.isActive=!1,this.clearTimer(),this.lastTimestamp=void 0):console.warn("Lag monitor is not running")}reset(){this.lagSamples.clear(),this.lastTimestamp=performance.now(),this.isActive=!1,this.clearTimer(),this.timerId=null}restart(){this.reset(),this.start()}isRunning(){return this.isActive}} /** * Event Loop Lag Monitor * * A lightweight utility for monitoring JavaScript event loop lag in real-time. * Useful for performance monitoring, debugging, and alerting on event loop blocking. * * @author Your Name * @version 1.0.0 * @license MIT */t.CircularBuffer=e,t.LagMonitor=s,t.default=s,Object.defineProperty(t,"__esModule",{value:!0})}));