nv-test-perf-block
v1.0.2
Published
A lightweight, zero-dependency performance monitoring library for Node.js and browsers, leveraging JavaScript's [Explicit Resource Management](https://github.com/tc39/proposal-explicit-resource-management) (using/await using) for block-level performance t
Downloads
193
Readme
Perf-Block: Performance Monitoring with Explicit Resource Management
A lightweight, zero-dependency performance monitoring library for Node.js and browsers, leveraging JavaScript's Explicit Resource Management (using/await using) for block-level performance tracking.
Features
✅ Block-scoped monitoring - Uses using/await using syntax for automatic lifecycle management
✅ Memory tracking - Monitors heap memory usage before/after execution
✅ Zero dependencies - Pure JavaScript, no external packages
✅ Universal - Works in both Node.js and browsers
✅ Async support - Full support for synchronous and asynchronous code blocks
✅ Statistical analysis - Built-in summary statistics (avg, min, max)
Requirements
- Node.js 22+ (with Explicit Resource Management support)
- Or any environment that supports
DisposableStackandAsyncDisposableStack
Installation
npm install nv-test-perf-blockQuick Start
Synchronous Code
const perf = require('nv-test-perf-block');
// Measure a loop
{
using _ = perf.sbegin("for-loop");
for(let i = 0; i < 50000000; i++) {}
}Output:
┌─────────┬────────────┬────────────┬──────────────────────────┬────────────────────┬─────────┐
│ (index) │ name │ stage │ date │ ms │ mem(MB) │
├─────────┼────────────┼────────────┼──────────────────────────┼────────────────────┼─────────┤
│ 0 │ 'for-loop' │ 'bgn at' │ 2026-03-03T11:44:05.102Z │ 1772538262571.9453 │ 6.36 │
│ 1 │ │ 'end at' │ 2026-03-03T11:44:05.397Z │ 1772538263158.732 │ 6.38 │
│ 2 │ │ 'costed' │ │ 586.7866 │ 0.02 │
└─────────┴────────────┴────────────┴──────────────────────────┴────────────────────┴─────────┘Asynchronous Code
const perf = require('./perf-block.js');
async function processData() {
await using _ = perf.abegin("async-task");
await fetch('https://api.example.com/data');
// Your async code here
}API Reference
sbegin(name, show = true)
Start synchronous performance monitoring.
Parameters:
name(string) - Unique identifier for this measurementshow(boolean, optional) - Whether to display results immediately (default:true)
Returns: DisposableStack - Automatically disposed when leaving scope
Example:
{
using _ = perf.sbegin("compute");
// Your synchronous code
}abegin(name, show = true)
Start asynchronous performance monitoring.
Parameters:
name(string) - Unique identifier for this measurementshow(boolean, optional) - Whether to display results immediately (default:true)
Returns: AsyncDisposableStack - Automatically disposed when leaving async scope
Example:
{
await using _ = perf.abegin("fetch-data");
await someAsyncOperation();
}summary(name)
Display statistical summary for a named measurement.
Parameters:
name(string) - The measurement name to summarize
Returns: Object containing statistics or null if no data
Example:
perf.summary("my-task");Output:
┌─────────┬──────────┬───────┬──────────┬──────────┬──────────┬──────────┐
│ (index) │ name │ count │ total │ avg │ min │ max │
├─────────┼──────────┼───────┼──────────┼──────────┼──────────┼──────────┤
│ 0 │ 'my-task'│ 5 │ '234.5ms'│ '46.9ms' │ '42.1ms' │ '58.3ms' │
└─────────┴──────────┴───────┴──────────┴──────────┴──────────┴──────────┘memSnapshot()
Display current memory usage snapshot.
Example:
perf.memSnapshot();clear()
Clear all stored measurements.
Example:
perf.clear();Usage Examples
Basic Measurement
const perf = require('nv-test-perf-block');
{
using _ = perf.sbegin("array-sort");
const arr = Array.from({length: 100000}, () => Math.random());
arr.sort();
}Nested Measurements
{
using _outer = perf.sbegin("full-process");
{
using _inner = perf.sbegin("data-load");
// Load data
}
{
using _inner = perf.sbegin("data-process");
// Process data
}
}Async with Error Handling
async function fetchWithRetry() {
await using _ = perf.abegin("fetch-retry");
try {
const response = await fetch('https://api.example.com/data');
return await response.json();
} catch (error) {
console.error('Fetch failed:', error);
throw error;
}
// Performance is recorded even if error occurs
}Silent Mode (No Output)
{
using _ = perf.sbegin("silent-task", false);
// Your code - no console output
}
// Later, get statistics
perf.summary("silent-task");Multiple Samples
// Run same task multiple times
for (let i = 0; i < 10; i++) {
using _ = perf.sbegin("task-iteration", false);
// Your repeated task
}
// Show statistics for all iterations
perf.summary("task-iteration");Browser Usage
<!DOCTYPE html>
<html>
<head>
<script src="./DIST/nv-test-perf-block-bw.js"></script>
</head>
<body>
<script>
// Note: Browser support for using/await using may vary
// Check compatibility first
// window.nvtestperfblock
async function loadData() {
await using _ = nvtestperfblock.abegin("page-load");
const response = await fetch('/api/data');
const data = await response.json();
renderData(data);
}
loadData();
</script>
</body>
</html>Output Format
Each measurement displays a 3-row table:
| Row | Stage | Description | |-----|------------|--------------------------------------| | 0 | bgn at | Start time and initial memory | | 1 | end at | End time and final memory | | 2 | costed | Total duration and memory difference |
Columns:
name- Measurement identifier (only in first row)stage- Current stage (bgn at / end at / costed)date- Timestamp (Date object)ms- Milliseconds (high-resolution)mem(MB)- Memory usage in MB (heapUsed in Node.js, usedJSHeapSize in browsers)
Memory Monitoring
Node.js
Tracks process.memoryUsage().heapUsed - the actual heap memory being used by V8.
Browser
Tracks performance.memory.usedJSHeapSize (Chrome/Edge only) - the total allocated heap.
Note: Memory tracking may not be available in all browsers. Use feature detection:
if (performance.memory) {
// Memory tracking available
}Implementation Details
Architecture
perf-block.js
├── getMemoryInfo() # Memory snapshot helper
├── Costed (class)
│ ├── _startRecord() # Initialize measurement
│ ├── _endRecord() # Finalize and display
│ ├── sbegin() # Sync using DisposableStack
│ ├── abegin() # Async using AsyncDisposableStack
│ ├── summary() # Statistical analysis
│ ├── memSnapshot() # Current memory info
│ └── clear() # Reset all data
└── G (singleton instance)How It Works
- Start:
_startRecord()captures timestamp and memory - Execute: Your code runs within using/await using block
- End: Disposal triggers
_endRecord()which calculates duration and memory delta - Display: Results are output to
console.table()
Data Structure
samples = {
"task-name": [
{
bgn: [Date.now(), performance.now()],
memBgn: { heapUsed: "6.36", ... },
end: [Date.now(), performance.now()],
memEnd: { heapUsed: "6.38", ... },
costed: 586.7866
},
// ... more samples
]
}Browser Compatibility
| Feature | Node.js | Chrome/Edge | Firefox | Safari | |--------------------------|---------|-------------|---------|--------| | using/await using | 22+ | 127+ | 130+ | 18+ | | DisposableStack | 22+ | 127+ | 130+ | 18+ | | performance.now() | ✅ | ✅ | ✅ | ✅ | | performance.memory | ❌ | ✅ | ❌ | ❌ |
Note: Explicit Resource Management is a Stage 3 TC39 proposal. Browser support is evolving.
Best Practices
- Use meaningful names - Makes summary statistics easier to interpret
- Silent mode for loops - Use
show=falsefor repeated measurements - Check memory support - Not all environments support memory tracking
- Nested measurements - Use descriptive names to differentiate levels
- Summary analysis - Call
summary()after multiple samples for insights
Limitations
- Memory tracking - Browser support is limited (Chrome/Edge only)
- Overhead - Minimal but adds ~0.1ms per measurement
- No persistence - Data is stored in memory only (cleared on restart)
- Single-threaded - Results may vary with concurrent operations
Performance Tips
- Disable logging with
show=falsein production - Use
clear()periodically to prevent memory buildup - For micro-benchmarks, run multiple iterations and use
summary()
Troubleshooting
"DisposableStack is not defined"
- Your environment doesn't support Explicit Resource Management
- Upgrade to Node.js 22+ or use a compatible browser
"performance.memory is undefined"
- Memory tracking unavailable in your browser
- This is normal for Firefox/Safari; only basic timing will work
License
ANY
