UNPKG

speedact

Version:

A modern library for measuring React component performance

3 lines (2 loc) 7.68 kB
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react/jsx-runtime"),require("react")):"function"==typeof define&&define.amd?define(["exports","react/jsx-runtime","react"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).SpeedAct={},e.jsxRuntime,e.React)}(this,(function(e,t,r){"use strict";var n=Object.defineProperty,o=(e,t)=>n(e,"name",{value:t,configurable:!0}),s=Object.defineProperty,i=o(((e,t,r)=>t in e?s(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r),"__defNormalProp"),a=o(((e,t,r)=>i(e,"symbol"!=typeof t?t+"":t,r)),"__publicField");const c=class{constructor(e=100){a(this,"renders",[]),a(this,"maxSamples"),a(this,"head",0),a(this,"size",0),this.maxSamples=Math.max(1,Math.min(1e3,e)),this.renders=new Array(this.maxSamples)}addRender(e){try{if(!e||"number"!=typeof e.duration)return void("production"!==process.env.NODE_ENV&&console.warn("SpeedAct: Invalid render info provided"));if(e.duration<0||!isFinite(e.duration))return void("production"!==process.env.NODE_ENV&&console.warn("SpeedAct: Invalid render duration:",e.duration));this.renders[this.head]={...e},this.head=(this.head+1)%this.maxSamples,this.size<this.maxSamples&&this.size++}catch(t){console.error("SpeedAct: Error adding render info:",t)}}getMetrics(e){var t,r;try{if(0===this.size)return this.getEmptyMetrics(e);const n=this.getValidDurations();if(0===n.length)return this.getEmptyMetrics(e);const o=n.reduce(((e,t)=>e+t),0),s=o/n.length,i=Math.max(...n),a=Math.min(...n),c=null!=(r=null==(t=this.getLastValidRender())?void 0:t.duration)?r:0,l={renderCount:this.size,totalRenderTime:Number(o.toFixed(3)),averageRenderTime:Number(s.toFixed(3)),longestRenderTime:Number(i.toFixed(3)),shortestRenderTime:Number(a.toFixed(3)),lastRenderTime:Number(c.toFixed(3)),timestamp:Date.now()};return e&&(l.componentName=e),l}catch(n){return console.error("SpeedAct: Error calculating metrics:",n),this.getEmptyMetrics(e)}}getValidDurations(){const e=[],t=Math.min(this.size,this.maxSamples);for(let r=0;r<t;r++){const t=this.renders[r];t&&"number"==typeof t.duration&&t.duration>=0&&isFinite(t.duration)&&e.push(t.duration)}return e}getLastValidRender(){const e=Math.min(this.size,this.maxSamples);for(let t=1;t<=e;t++){const e=(this.head-t+this.maxSamples)%this.maxSamples,r=this.renders[e];if(r&&"number"==typeof r.duration&&r.duration>=0&&isFinite(r.duration))return r}return null}getEmptyMetrics(e){const t={renderCount:0,totalRenderTime:0,averageRenderTime:0,longestRenderTime:0,shortestRenderTime:0,lastRenderTime:0,timestamp:Date.now()};return e&&(t.componentName=e),t}reset(){try{this.renders=new Array(this.maxSamples),this.head=0,this.size=0}catch(e){console.error("SpeedAct: Error resetting metrics calculator:",e)}}getRenderHistory(){try{const e=[],t=Math.min(this.size,this.maxSamples);for(let r=0;r<t;r++){const t=this.renders[r];t&&e.push({...t})}return e.sort(((e,t)=>e.startTime-t.startTime))}catch(e){return console.error("SpeedAct: Error getting render history:",e),[]}}getMemoryUsage(){try{const e=this.size,t=this.maxSamples;return{usedSlots:e,totalSlots:t,memoryEfficiency:Number((t>0?e/t*100:0).toFixed(2))}}catch(e){return console.error("SpeedAct: Error calculating memory usage:",e),{usedSlots:0,totalSlots:0,memoryEfficiency:0}}}};o(c,"MetricsCalculator");let l=c;const m=class{static log(e,t){var r;try{if(!e||"number"!=typeof e.lastRenderTime)return;const n=this.determineLogLevel(e.lastRenderTime,t),o=`SpeedAct [${null!=(r=e.componentName)?r:"Unknown"}]: ${e.lastRenderTime.toFixed(2)}ms (avg: ${e.averageRenderTime.toFixed(2)}ms, renders: ${e.renderCount})`;switch(n){case"error":console.error(`🔴 ${o}`);break;case"warn":console.warn(`🟡 ${o}`);break;case"info":console.log(`🟢 ${o}`);break;default:console.log(o)}t&&e.lastRenderTime>2*t&&(console.group("Performance Analysis"),console.log(this.generateAnalysis(e)),console.groupEnd())}catch(n){console.error("SpeedAct: Error logging performance metrics:",n)}}static determineLogLevel(e,t){const r=null!=t?t:16;return e>3*r?"error":e>r?"warn":"info"}static generateReport(e){var t;try{let r=`Performance Report: ${null!=(t=e.componentName)?t:"Unknown Component"}\n`;return r+="=".repeat(40)+"\n",r+=`Render Count: ${e.renderCount}\n`,r+=`Total Time: ${e.totalRenderTime.toFixed(2)}ms\n`,r+=`Average Time: ${e.averageRenderTime.toFixed(2)}ms\n`,r+=`Longest Render: ${e.longestRenderTime.toFixed(2)}ms\n`,r+=`Shortest Render: ${e.shortestRenderTime.toFixed(2)}ms\n`,r+=`Last Render: ${e.lastRenderTime.toFixed(2)}ms\n`,r+=`Timestamp: ${new Date(e.timestamp).toISOString()}\n\n`,r+=this.generateAnalysis(e),r}catch(r){return console.error("SpeedAct: Error generating report:",r),"Error generating performance report"}}static generateAnalysis(e){try{const t=[],r=this.calculateGrade(e.averageRenderTime);t.push(`Performance Grade: ${r}`);const n=e.longestRenderTime-e.shortestRenderTime,o=this.calculateConsistency(n);return t.push(`Consistency: ${o}`),e.averageRenderTime>16&&t.push("⚠️ Consider optimizing render performance"),n>50&&t.push("⚠️ High render time variance detected"),e.renderCount>100&&t.push("ℹ️ High render count - consider memoization"),t.join("\n")}catch(t){return console.error("SpeedAct: Error generating analysis:",t),"Analysis unavailable"}}static calculateGrade(e){return e<16?"A (Excellent)":e<33?"B (Good)":e<50?"C (Fair)":"D (Poor)"}static calculateConsistency(e){return e<5?"Excellent":e<20?"Good":e<50?"Fair":"Poor"}};o(m,"PerformanceLogger");let d=m;function u(){try{return"undefined"!=typeof performance&&"function"==typeof performance.now&&"function"==typeof performance.mark&&"function"==typeof performance.measure}catch(e){return!1}}o(u,"isPerformanceAPIAvailable");const p=new Map,h=new Map;function g(e){const t=h.get(e);t&&clearTimeout(t);const r=setTimeout((()=>{p.delete(e),h.delete(e)}),3e5);h.set(e,r)}function f(e){const t=h.get(e);t&&(clearTimeout(t),h.delete(e))}function y({children:e,componentName:n="PerformanceMonitor",onMetricsUpdate:o,logToConsole:s=!1,threshold:i=16,enabled:a=!0,maxSamples:c=100}){r.useEffect((()=>(a&&!p.has(n)&&p.set(n,new l(c)),a&&f(n),()=>{a&&g(n)})),[n,c,a]);const m=r.useCallback(((e,t,r,c,l,m)=>{try{if(!a||!u())return;const e=p.get(n);if(!e)return;const t={startTime:l,endTime:m,duration:r,renderCount:e.getMetrics().renderCount+1,componentName:n};e.addRender(t);const c=e.getMetrics(n);s&&d.log(c,i),o&&o(c)}catch(h){console.error("Error in PerformanceMonitor callback:",h)}}),[n,a,s,i,o]);return a?t.jsx(r.Profiler,{id:n,onRender:m,children:e}):t.jsx(t.Fragment,{children:e})}o(g,"scheduleCleanup"),o(f,"cancelCleanup"),o(y,"PerformanceMonitor");const R={getComponentMetrics:o((e=>{const t=p.get(e);return t?t.getMetrics(e):null}),"getComponentMetrics"),resetComponentMetrics:o((e=>{const t=p.get(e);t&&t.reset()}),"resetComponentMetrics"),getAllComponentNames:o((()=>Array.from(p.keys())),"getAllComponentNames"),getAllMetrics:o((()=>{const e={};for(const[t,r]of p.entries())e[t]=r.getMetrics(t);return e}),"getAllMetrics"),resetAllMetrics:o((()=>{for(const e of p.values())e.reset()}),"resetAllMetrics"),generateGlobalReport:o((()=>{const e=R.getAllMetrics();let t="Global Performance Report\n";t+="========================\n\n";for(const[,r]of Object.entries(e))t+=d.generateReport(r),t+="\n\n";return t}),"generateGlobalReport"),forceCleanup:o((()=>{p.clear();for(const e of h.values())clearTimeout(e);h.clear()}),"forceCleanup"),getActiveComponentsCount:o((()=>p.size),"getActiveComponentsCount")};e.MetricsCalculator=l,e.PerformanceLogger=d,e.PerformanceMonitor=y,e.PerformanceUtils=R,e.isPerformanceAPIAvailable=u})); //# sourceMappingURL=index.umd.js.map