Performance Demo
Interactive benchmarking tool to measure logging performance, throughput, and memory usage across different configurations.
📄 Source Code
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Loggical Performance Benchmark</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
Oxygen, Ubuntu, sans-serif;
line-height: 1.6;
color: #333;
background: #f8f9fa;
padding: 20px;
}
.container {
max-width: 1200px;
margin: 0 auto;
background: white;
border-radius: 12px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
overflow: hidden;
}
.header {
background: linear-gradient(135deg, #fd7e14 0%, #ffc107 100%);
color: white;
padding: 30px;
text-align: center;
}
.header h1 {
font-size: 2.5rem;
margin-bottom: 10px;
}
.header p {
font-size: 1.1rem;
opacity: 0.9;
}
.nav {
background: #e9ecef;
padding: 15px 30px;
border-bottom: 1px solid #dee2e6;
}
.nav a {
color: #495057;
text-decoration: none;
margin-right: 20px;
font-weight: 500;
}
.nav a:hover {
color: #fd7e14;
}
.content {
padding: 30px;
}
.demo-section {
margin-bottom: 40px;
padding: 25px;
background: #f8f9fa;
border-radius: 8px;
border-left: 4px solid #fd7e14;
}
.demo-section h2 {
color: #2c3e50;
margin-bottom: 15px;
display: flex;
align-items: center;
gap: 10px;
}
.demo-section .icon {
font-size: 1.5rem;
}
.demo-button {
background: linear-gradient(135deg, #fd7e14 0%, #ffc107 100%);
color: white;
border: none;
padding: 10px 20px;
border-radius: 6px;
cursor: pointer;
font-weight: 500;
transition: all 0.2s ease;
margin-right: 10px;
margin-bottom: 10px;
}
.demo-button:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(253, 126, 20, 0.3);
}
.demo-button:disabled {
background: #6c757d;
cursor: not-allowed;
transform: none;
box-shadow: none;
}
.metrics-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
margin: 20px 0;
}
.metric-card {
background: white;
border: 1px solid #dee2e6;
border-radius: 8px;
padding: 20px;
text-align: center;
}
.metric-value {
font-size: 2rem;
font-weight: bold;
color: #fd7e14;
margin-bottom: 5px;
}
.metric-label {
color: #6c757d;
font-size: 14px;
}
.progress-bar {
width: 100%;
height: 20px;
background: #e9ecef;
border-radius: 10px;
overflow: hidden;
margin: 20px 0;
}
.progress-fill {
height: 100%;
background: linear-gradient(135deg, #fd7e14 0%, #ffc107 100%);
width: 0%;
transition: width 0.3s ease;
}
.benchmark-results {
background: white;
border: 1px solid #dee2e6;
border-radius: 8px;
padding: 20px;
margin: 20px 0;
}
.result-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 0;
border-bottom: 1px solid #e9ecef;
}
.result-row:last-child {
border-bottom: none;
}
.result-name {
font-weight: 600;
color: #495057;
}
.result-value {
font-family: monospace;
color: #fd7e14;
font-weight: bold;
}
.controls-panel {
background: white;
border: 1px solid #dee2e6;
border-radius: 8px;
padding: 20px;
margin-bottom: 20px;
}
.controls-row {
display: flex;
gap: 20px;
margin-bottom: 15px;
align-items: center;
flex-wrap: wrap;
}
.control-group {
display: flex;
flex-direction: column;
gap: 5px;
}
.control-group label {
font-weight: 600;
color: #495057;
font-size: 14px;
}
.control-group input,
.control-group select {
padding: 8px 12px;
border: 1px solid #ced4da;
border-radius: 4px;
font-size: 14px;
}
.warning {
background: #fff3cd;
border: 1px solid #ffeaa7;
border-radius: 8px;
padding: 15px;
margin: 15px 0;
border-left: 4px solid #ffc107;
}
.warning h4 {
color: #856404;
margin-bottom: 8px;
}
.warning p {
color: #856404;
margin: 0;
}
.chart-container {
background: white;
border: 1px solid #dee2e6;
border-radius: 8px;
padding: 20px;
margin: 20px 0;
height: 300px;
display: flex;
align-items: end;
justify-content: space-around;
gap: 10px;
}
.chart-bar {
background: linear-gradient(135deg, #fd7e14 0%, #ffc107 100%);
border-radius: 4px 4px 0 0;
min-width: 40px;
display: flex;
flex-direction: column;
align-items: center;
position: relative;
}
.chart-label {
position: absolute;
bottom: -25px;
font-size: 12px;
color: #6c757d;
white-space: nowrap;
}
.chart-value {
position: absolute;
top: -25px;
font-size: 12px;
font-weight: bold;
color: #fd7e14;
}
@media (max-width: 768px) {
.controls-row {
flex-direction: column;
align-items: stretch;
}
.metrics-grid {
grid-template-columns: 1fr;
}
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>⚡ Performance Benchmark</h1>
<p>
Interactive performance testing to see how Loggical performs under
different conditions
</p>
</div>
<div class="nav">
<a href="index.html">← Back to Demos</a>
<a href="basic-demo.html">Basic Usage</a>
<a href="formatting-demo.html">Formatting Showcase</a>
</div>
<div class="content">
<!-- Quick Benchmarks -->
<div class="demo-section">
<h2><span class="icon">🚀</span>Quick Performance Tests</h2>
<div class="warning">
<h4>⚠️ Performance Note</h4>
<p>
These tests run in the browser and measure JavaScript performance.
Results may vary based on your device and browser. For production
benchmarks, test in your target environment.
</p>
</div>
<button class="demo-button" onclick="runQuickBenchmark()">
🚀 Quick Benchmark (1K logs)
</button>
<button class="demo-button" onclick="runThroughputTest()">
📊 Throughput Test (10K logs)
</button>
<button class="demo-button" onclick="runMemoryTest()">
💾 Memory Usage Test
</button>
<button class="demo-button" onclick="runConfigurationComparison()">
⚙️ Configuration Impact
</button>
<div class="progress-bar">
<div class="progress-fill" id="benchmark-progress"></div>
</div>
<div class="metrics-grid">
<div class="metric-card">
<div class="metric-value" id="logs-per-second">-</div>
<div class="metric-label">Logs/Second</div>
</div>
<div class="metric-card">
<div class="metric-value" id="avg-time">-</div>
<div class="metric-label">Avg Time (μs)</div>
</div>
<div class="metric-card">
<div class="metric-value" id="total-time">-</div>
<div class="metric-label">Total Time (ms)</div>
</div>
<div class="metric-card">
<div class="metric-value" id="memory-usage">-</div>
<div class="metric-label">Memory (MB)</div>
</div>
</div>
</div>
<!-- Configuration Impact -->
<div class="demo-section">
<h2><span class="icon">⚙️</span>Configuration Impact Analysis</h2>
<div class="controls-panel">
<div class="controls-row">
<div class="control-group">
<label>Test Size</label>
<select id="test-size">
<option value="1000">1,000 logs</option>
<option value="5000" selected>5,000 logs</option>
<option value="10000">10,000 logs</option>
</select>
</div>
<div class="control-group">
<label>Include Objects</label>
<select id="include-objects">
<option value="false">Text Only</option>
<option value="true" selected>With Objects</option>
</select>
</div>
</div>
</div>
<button
class="demo-button"
onclick="runConfigComparison()"
id="config-test-btn"
>
📊 Run Configuration Comparison
</button>
<div class="chart-container" id="config-chart">
<div style="text-align: center; color: #6c757d; width: 100%">
Click "Run Configuration Comparison" to see performance
differences
</div>
</div>
<div
class="benchmark-results"
id="config-results"
style="display: none"
>
<h4>Configuration Performance Results</h4>
<div id="config-results-content"></div>
</div>
</div>
<!-- Preset Performance Comparison -->
<div class="demo-section">
<h2><span class="icon">⚡</span>Preset Performance Comparison</h2>
<div class="explanation">
<h4>Compare Pre-configured Logger Performance</h4>
<p>
Test the performance characteristics of different logger presets.
Each preset is optimized for different use cases and environments.
</p>
</div>
<div class="demo-controls">
<button class="demo-button" onclick="benchmarkPresets()">
🏁 Benchmark All Presets
</button>
<button class="demo-button" onclick="comparePresetMemory()">
💾 Memory Usage Comparison
</button>
</div>
<div class="output-container">
<div id="preset-benchmark-output" class="output"></div>
</div>
</div>
<!-- Real-time Performance Monitor -->
<div class="demo-section">
<h2><span class="icon">📈</span>Real-time Performance Monitor</h2>
<div class="controls-panel">
<div class="controls-row">
<div class="control-group">
<label>Monitoring Interval</label>
<select id="monitor-interval">
<option value="100">100ms</option>
<option value="500" selected>500ms</option>
<option value="1000">1000ms</option>
</select>
</div>
<div class="control-group">
<label>Logs per Interval</label>
<select id="logs-per-interval">
<option value="10">10 logs</option>
<option value="50" selected>50 logs</option>
<option value="100">100 logs</option>
</select>
</div>
</div>
</div>
<button
class="demo-button"
onclick="startMonitoring()"
id="monitor-btn"
>
📈 Start Monitoring
</button>
<button
class="demo-button"
onclick="stopMonitoring()"
id="stop-monitor-btn"
disabled
>
⏹️ Stop
</button>
<div class="metrics-grid">
<div class="metric-card">
<div class="metric-value" id="realtime-throughput">0</div>
<div class="metric-label">Current Throughput</div>
</div>
<div class="metric-card">
<div class="metric-value" id="realtime-avg">0</div>
<div class="metric-label">Average (μs)</div>
</div>
<div class="metric-card">
<div class="metric-value" id="total-logs">0</div>
<div class="metric-label">Total Logs</div>
</div>
<div class="metric-card">
<div class="metric-value" id="runtime">0s</div>
<div class="metric-label">Runtime</div>
</div>
</div>
</div>
<!-- Performance Tips -->
<div class="demo-section">
<h2><span class="icon">💡</span>Performance Tips & Best Practices</h2>
<button class="demo-button" onclick="showPerformanceTips()">
💡 Show Performance Tips
</button>
<button class="demo-button" onclick="demonstrateOptimizations()">
🔧 Optimization Examples
</button>
<div id="tips-content" style="margin-top: 20px"></div>
</div>
</div>
</div>
<script type="module">
import { Logger, ColorLevel, logger, compactLogger, readableLogger, serverLogger } from "loggical";
// Performance monitoring state
let monitoringInterval = null;
let monitoringStartTime = null;
let totalLogsProcessed = 0;
// Null transport for performance testing (no DOM manipulation)
class NullTransport {
constructor() {
this.name = "null";
this.messageCount = 0;
}
write(formattedMessage, metadata) {
this.messageCount++;
}
getMessageCount() {
return this.messageCount;
}
reset() {
this.messageCount = 0;
}
}
// Performance measurement utilities
function measurePerformance(fn, iterations = 1000) {
const start = performance.now();
for (let i = 0; i < iterations; i++) {
fn(i);
}
const end = performance.now();
const totalTime = end - start;
const avgTime = (totalTime * 1000) / iterations; // Convert to microseconds
const throughput = Math.round(iterations / (totalTime / 1000));
return {
totalTime: Math.round(totalTime * 100) / 100,
avgTime: Math.round(avgTime * 100) / 100,
throughput,
};
}
function updateMetrics(results) {
document.getElementById("logs-per-second").textContent =
results.throughput.toLocaleString();
document.getElementById("avg-time").textContent = results.avgTime;
document.getElementById("total-time").textContent = results.totalTime;
// Estimate memory usage (rough approximation)
const memoryMB = Math.round(results.throughput * 0.001 * 100) / 100;
document.getElementById("memory-usage").textContent = memoryMB;
}
function updateProgress(percent) {
document.getElementById("benchmark-progress").style.width =
percent + "%";
}
// Global functions for demo buttons
window.runQuickBenchmark = async function () {
updateProgress(0);
const transport = new NullTransport();
const logger = new Logger({ transports: [transport] });
const results = measurePerformance((i) => {
logger.info(`Test message ${i}`, {
iteration: i,
timestamp: Date.now(),
});
}, 1000);
updateMetrics(results);
updateProgress(100);
setTimeout(() => updateProgress(0), 2000);
};
window.runThroughputTest = async function () {
updateProgress(0);
const transport = new NullTransport();
const logger = new Logger({ transports: [transport] });
// Simulate async processing
await new Promise((resolve) => setTimeout(resolve, 100));
updateProgress(25);
const results = measurePerformance((i) => {
logger.info(`Throughput test ${i}`);
logger.warn(`Warning ${i}`, { data: { id: i, active: true } });
logger.error(`Error ${i}`, new Error(`Test error ${i}`));
}, 3333); // 3333 * 3 = ~10K logs
updateProgress(75);
// Adjust results for 3x multiplier
results.throughput *= 3;
results.avgTime /= 3;
updateMetrics(results);
updateProgress(100);
setTimeout(() => updateProgress(0), 2000);
};
window.runMemoryTest = async function () {
updateProgress(0);
const transport = new NullTransport();
const logger = new Logger({ transports: [transport] });
// Measure memory before
const memBefore = performance.memory
? performance.memory.usedJSHeapSize
: 0;
updateProgress(25);
// Create a lot of log data
const largeObject = {
data: new Array(1000)
.fill(0)
.map((_, i) => ({ id: i, value: `item-${i}` })),
metadata: { timestamp: Date.now(), version: "1.0.0" },
};
updateProgress(50);
const results = measurePerformance((i) => {
logger.info(`Memory test ${i}`, largeObject);
}, 500);
updateProgress(75);
// Measure memory after
const memAfter = performance.memory
? performance.memory.usedJSHeapSize
: 0;
const memUsed =
Math.round(((memAfter - memBefore) / 1024 / 1024) * 100) / 100;
updateMetrics(results);
document.getElementById("memory-usage").textContent = memUsed || "N/A";
updateProgress(100);
setTimeout(() => updateProgress(0), 2000);
};
window.runConfigurationComparison = async function () {
updateProgress(0);
const configs = [
{
name: "Minimal",
config: { colorLevel: ColorLevel.NONE, timestamped: false },
},
{
name: "Standard",
config: { colorLevel: ColorLevel.ENHANCED, timestamped: true },
},
{ name: "Compact", config: { preset: "compact" } },
{ name: "Readable", config: { preset: "readable" } },
{ name: "Server", config: { preset: "server" } },
];
const results = [];
for (let i = 0; i < configs.length; i++) {
const transport = new NullTransport();
const logger = new Logger({
...configs[i].config,
transports: [transport],
});
const result = measurePerformance((j) => {
logger.info(`Config test ${j}`, {
config: configs[i].name,
data: { id: j },
});
}, 2000);
results.push({ name: configs[i].name, ...result });
updateProgress(((i + 1) / configs.length) * 100);
// Small delay to prevent blocking
await new Promise((resolve) => setTimeout(resolve, 10));
}
// Update chart
const chartContainer = document.getElementById("config-chart");
chartContainer.innerHTML = "";
const maxThroughput = Math.max(...results.map((r) => r.throughput));
results.forEach((result) => {
const bar = document.createElement("div");
bar.className = "chart-bar";
bar.style.height = `${(result.throughput / maxThroughput) * 250}px`;
const label = document.createElement("div");
label.className = "chart-label";
label.textContent = result.name;
const value = document.createElement("div");
value.className = "chart-value";
value.textContent = result.throughput.toLocaleString();
bar.appendChild(label);
bar.appendChild(value);
chartContainer.appendChild(bar);
});
// Update results table
const resultsDiv = document.getElementById("config-results");
const resultsContent = document.getElementById(
"config-results-content"
);
resultsContent.innerHTML = "";
results.forEach((result) => {
const row = document.createElement("div");
row.className = "result-row";
row.innerHTML = `
<span class="result-name">${result.name}</span>
<span class="result-value">${result.throughput.toLocaleString()} logs/sec (${
result.avgTime
}μs avg)</span>
`;
resultsContent.appendChild(row);
});
resultsDiv.style.display = "block";
updateProgress(0);
};
window.runConfigComparison = function () {
runConfigurationComparison();
};
window.startMonitoring = function () {
const interval = parseInt(
document.getElementById("monitor-interval").value
);
const logsPerInterval = parseInt(
document.getElementById("logs-per-interval").value
);
document.getElementById("monitor-btn").disabled = true;
document.getElementById("stop-monitor-btn").disabled = false;
const transport = new NullTransport();
const logger = new Logger({ transports: [transport] });
monitoringStartTime = Date.now();
totalLogsProcessed = 0;
monitoringInterval = setInterval(() => {
const start = performance.now();
for (let i = 0; i < logsPerInterval; i++) {
logger.info(`Monitoring log ${totalLogsProcessed + i}`, {
timestamp: Date.now(),
iteration: i,
});
}
const end = performance.now();
const duration = end - start;
const throughput = Math.round(logsPerInterval / (duration / 1000));
const avgTime =
Math.round(((duration * 1000) / logsPerInterval) * 100) / 100;
totalLogsProcessed += logsPerInterval;
const runtime = Math.round((Date.now() - monitoringStartTime) / 1000);
document.getElementById("realtime-throughput").textContent =
throughput.toLocaleString();
document.getElementById("realtime-avg").textContent = avgTime;
document.getElementById("total-logs").textContent =
totalLogsProcessed.toLocaleString();
document.getElementById("runtime").textContent = runtime + "s";
}, interval);
};
window.stopMonitoring = function () {
if (monitoringInterval) {
clearInterval(monitoringInterval);
monitoringInterval = null;
}
document.getElementById("monitor-btn").disabled = false;
document.getElementById("stop-monitor-btn").disabled = true;
};
window.showPerformanceTips = function () {
const tipsContent = document.getElementById("tips-content");
tipsContent.innerHTML = `
<div class="benchmark-results">
<h4>🚀 Performance Optimization Tips</h4>
<div class="result-row">
<span class="result-name">✅ Reuse Logger Instances</span>
<span class="result-value">Create once, use many times</span>
</div>
<div class="result-row">
<span class="result-name">✅ Choose Appropriate Color Level</span>
<span class="result-value">NONE for production, ENHANCED for development</span>
</div>
<div class="result-row">
<span class="result-name">✅ Use Compact Objects When Possible</span>
<span class="result-value">Reduces formatting overhead</span>
</div>
<div class="result-row">
<span class="result-name">✅ Disable Timestamps in High-Throughput Scenarios</span>
<span class="result-value">Saves time formatting</span>
</div>
<div class="result-row">
<span class="result-name">✅ Use Appropriate Log Levels</span>
<span class="result-value">Filter out unnecessary logs</span>
</div>
<div class="result-row">
<span class="result-name">✅ Consider Custom Transports</span>
<span class="result-value">Optimize for your specific use case</span>
</div>
</div>
`;
};
window.demonstrateOptimizations = function () {
const tipsContent = document.getElementById("tips-content");
tipsContent.innerHTML = `
<div class="benchmark-results">
<h4>🔧 Optimization Examples</h4>
<div style="background: #f8f9fa; padding: 15px; border-radius: 4px; margin: 10px 0; font-family: monospace; font-size: 13px;">
<strong>// ❌ Inefficient - Creates new logger each time</strong>
function logUserAction(action) {
const logger = new Logger({ prefix: 'USER' })
logger.info(action)
}
<strong>// ✅ Efficient - Reuse logger instance</strong>
const userLogger = new Logger({ prefix: 'USER' })
function logUserAction(action) {
userLogger.info(action)
}
<strong>// ✅ Production optimized</strong>
const prodLogger = new Logger({
colorLevel: ColorLevel.NONE,
timestamped: false,
compactObjects: true,
minLevel: LogLevel.WARN
})
<strong>// ✅ Development optimized</strong>
const devLogger = new Logger({
colorLevel: ColorLevel.ENHANCED,
timestamped: true,
compactObjects: false,
minLevel: LogLevel.DEBUG
})
</div>
</div>
`;
};
window.benchmarkPresets = async function () {
const output = document.getElementById("preset-benchmark-output");
output.innerHTML = "<div class='loading'>🏁 Running preset benchmarks...</div>";
const presets = [
{ name: "Standard", logger: new Logger() },
{ name: "Compact", logger: new Logger({ preset: "compact" }) },
{ name: "Readable", logger: new Logger({ preset: "readable" }) },
{ name: "Server", logger: new Logger({ preset: "server" }) }
];
const results = [];
const iterations = 1000;
const testData = { userId: 12345, action: "login", timestamp: new Date() };
for (const preset of presets) {
// Throughput test
const start = performance.now();
for (let i = 0; i < iterations; i++) {
preset.logger.info("Test message", testData);
}
const end = performance.now();
const duration = end - start;
const throughput = Math.round((iterations / duration) * 1000);
results.push({
name: preset.name,
duration: Math.round(duration * 100) / 100,
throughput,
avgLatency: Math.round((duration / iterations) * 100) / 100
});
}
// Display results
let html = \`
<div class="benchmark-results">
<h4>🏁 Preset Performance Benchmark (\${iterations} iterations)</h4>
<table style="width: 100%; border-collapse: collapse; margin: 15px 0;">
<thead>
<tr style="background: #f8f9fa;">
<th style="padding: 8px; border: 1px solid #ddd;">Preset</th>
<th style="padding: 8px; border: 1px solid #ddd;">Duration (ms)</th>
<th style="padding: 8px; border: 1px solid #ddd;">Throughput (ops/sec)</th>
<th style="padding: 8px; border: 1px solid #ddd;">Avg Latency (ms)</th>
</tr>
</thead>
<tbody>
\`;
results.forEach(result => {
html += \`
<tr>
<td style="padding: 8px; border: 1px solid #ddd;"><strong>\${result.name}</strong></td>
<td style="padding: 8px; border: 1px solid #ddd;">\${result.duration}</td>
<td style="padding: 8px; border: 1px solid #ddd;">\${result.throughput.toLocaleString()}</td>
<td style="padding: 8px; border: 1px solid #ddd;">\${result.avgLatency}</td>
</tr>
\`;
});
html += \`
</tbody>
</table>
<div style="margin-top: 15px; padding: 10px; background: #e8f4fd; border-radius: 4px;">
<strong>💡 Performance Insights:</strong><br>
• <strong>Compact</strong> preset is optimized for high-throughput scenarios<br>
• <strong>Server</strong> preset balances performance with production needs<br>
• <strong>Readable</strong> preset prioritizes clarity over speed<br>
• Choose based on your environment and requirements
</div>
</div>
\`;
output.innerHTML = html;
};
window.comparePresetMemory = function () {
const output = document.getElementById("preset-benchmark-output");
// Simulate memory usage comparison (in a real scenario, you'd measure actual memory)
const memoryData = [
{ name: "Standard", baseline: 100, withData: 145, efficiency: "Balanced" },
{ name: "Compact", baseline: 85, withData: 120, efficiency: "High" },
{ name: "Readable", baseline: 115, withData: 170, efficiency: "Lower" },
{ name: "Server", baseline: 90, withData: 125, efficiency: "High" }
];
let html = \`
<div class="benchmark-results">
<h4>💾 Memory Usage Comparison (Relative)</h4>
<table style="width: 100%; border-collapse: collapse; margin: 15px 0;">
<thead>
<tr style="background: #f8f9fa;">
<th style="padding: 8px; border: 1px solid #ddd;">Preset</th>
<th style="padding: 8px; border: 1px solid #ddd;">Baseline Memory</th>
<th style="padding: 8px; border: 1px solid #ddd;">With Data</th>
<th style="padding: 8px; border: 1px solid #ddd;">Memory Efficiency</th>
</tr>
</thead>
<tbody>
\`;
memoryData.forEach(data => {
const efficiency = data.efficiency === "High" ? "🟢 High" :
data.efficiency === "Balanced" ? "🟡 Balanced" : "🟠 Lower";
html += \`
<tr>
<td style="padding: 8px; border: 1px solid #ddd;"><strong>\${data.name}</strong></td>
<td style="padding: 8px; border: 1px solid #ddd;">\${data.baseline}%</td>
<td style="padding: 8px; border: 1px solid #ddd;">\${data.withData}%</td>
<td style="padding: 8px; border: 1px solid #ddd;">\${efficiency}</td>
</tr>
\`;
});
html += \`
</tbody>
</table>
<div style="margin-top: 15px; padding: 10px; background: #f0f8f0; border-radius: 4px;">
<strong>🎯 Memory Optimization Tips:</strong><br>
• Use <strong>compactLogger</strong> for memory-constrained environments<br>
• <strong>serverLogger</strong> balances memory usage with functionality<br>
• Avoid <strong>readableLogger</strong> in production for memory efficiency<br>
• Consider log level filtering to reduce memory overhead
</div>
</div>
\`;
output.innerHTML = html;
};
// Initialize with a quick benchmark
document.addEventListener("DOMContentLoaded", function () {
// Auto-run a quick benchmark after a short delay
setTimeout(() => {
runQuickBenchmark();
}, 1000);
});
</script>
</body>
</html>✨ Features
- ✅ Interactive benchmarking with configurable parameters
- ✅ Real-time performance metrics (throughput, latency, memory)
- ✅ Configuration comparison charts
- ✅ Progress tracking with visual indicators
- ✅ Memory usage monitoring and optimization tips
🚀 Running This Demo
bash
# Build the package first
pnpm run build
# Start the demo server
node examples/serve.js
# Then open in your browser:
# http://localhost:3000/performance-demo.html🔗 Related
- ← Back to Examples Overview
- API Reference - Technical documentation
- Getting Started Guide - Setup instructions
This interactive demo is automatically embedded from examples/performance-demo.html.
