Performance Monitoring
Learn to monitor and optimize JavaScript application performance. This is a foundational concept in programming and web interactivity that professional developers rely on daily. The explanations below are written to be beginner-friendly while covering the depth and nuance that comes from real-world JavaScript experience. Take your time with each section and practice the examples
Performance Metrics
Monitor key performance indicators to ensure optimal user experience and application efficiency.. This is an essential concept that every JavaScript developer must understand thoroughly. In professional development environments, getting this right can mean the difference between code that works reliably and code that breaks in production. The following sections break this down into clear, digestible pieces with practical examples you can try immediately
Core Web Vitals
// Measuring Core Web Vitals
function measureWebVitals() {
// Largest Contentful Paint (LCP)
new PerformanceObserver((entryList) => {
const entries = entryList.getEntries();
const lastEntry = entries[entries.length - 1];
console.log('LCP:', lastEntry.startTime);
}).observe({ entryTypes: ['largest-contentful-paint'] });
// First Input Delay (FID)
new PerformanceObserver((entryList) => {
const entries = entryList.getEntries();
entries.forEach(entry => {
console.log('FID:', entry.processingStart - entry.startTime);
});
}).observe({ entryTypes: ['first-input'] });
// Cumulative Layout Shift (CLS)
let clsValue = 0;
new PerformanceObserver((entryList) => {
for (const entry of entryList.getEntries()) {
if (!entry.hadRecentInput) {
clsValue += entry.value;
}
}
console.log('CLS:', clsValue);
}).observe({ entryTypes: ['layout-shift'] });
}Memory Monitoring
// Memory usage monitoring
function monitorMemory() {
if (performance.memory) {
const memory = performance.memory;
console.log('Memory Usage:', {
used: Math.round(memory.usedJSHeapSize / 1024 / 1024) + ' MB',
total: Math.round(memory.totalJSHeapSize / 1024 / 1024) + ' MB',
limit: Math.round(memory.jsHeapSizeLimit / 1024 / 1024) + ' MB'
});
}
}
// Memory leak detection
class MemoryLeakDetector {
constructor() {
this.initialMemory = performance.memory?.usedJSHeapSize || 0;
this.interval = setInterval(() => this.checkMemory(), 5000);
}
checkMemory() {
const currentMemory = performance.memory?.usedJSHeapSize || 0;
const increase = currentMemory - this.initialMemory;
if (increase > 10 * 1024 * 1024) { // 10MB increase
console.warn('Potential memory leak detected!');
}
}
stop() {
clearInterval(this.interval);
}
}Performance Profiling
// Performance profiling
class PerformanceProfiler {
constructor() {
this.marks = new Map();
}
start(name) {
performance.mark(`${name}-start`);
this.marks.set(name, performance.now());
}
end(name) {
const startTime = this.marks.get(name);
if (startTime) {
const duration = performance.now() - startTime;
console.log(`${name} took ${duration.toFixed(2)}ms`);
this.marks.delete(name);
}
}
measure(name, fn) {
this.start(name);
const result = fn();
this.end(name);
return result;
}
}Bundle Analysis
// webpack-bundle-analyzer
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
plugins: [
new BundleAnalyzerPlugin({
analyzerMode: 'static',
openAnalyzer: false,
reportFilename: 'bundle-report.html'
})
]
};Mini-Project: Performance Dashboard
// Performance Dashboard
class PerformanceDashboard {
constructor() {
this.metrics = {
pageLoad: 0,
memoryUsage: 0,
errors: 0,
apiCalls: 0
};
this.init();
}
init() {
this.measurePageLoad();
this.trackMemoryUsage();
this.trackErrors();
this.trackApiCalls();
this.renderDashboard();
}
measurePageLoad() {
window.addEventListener('load', () => {
this.metrics.pageLoad = performance.now();
this.updateDashboard();
});
}
trackMemoryUsage() {
setInterval(() => {
if (performance.memory) {
this.metrics.memoryUsage = performance.memory.usedJSHeapSize;
this.updateDashboard();
}
}, 1000);
}
trackErrors() {
window.addEventListener('error', () => {
this.metrics.errors++;
this.updateDashboard();
});
}
trackApiCalls() {
const originalFetch = window.fetch;
window.fetch = (...args) => {
this.metrics.apiCalls++;
this.updateDashboard();
return originalFetch.apply(this, args);
};
}
renderDashboard() {
const dashboard = document.createElement('div');
dashboard.id = 'perf-dashboard';
dashboard.style.cssText = `
position: fixed;
top: 10px;
right: 10px;
background: #000;
color: #fff;
padding: 10px;
border-radius: 5px;
font-family: monospace;
z-index: 9999;
`;
document.body.appendChild(dashboard);
}
updateDashboard() {
const dashboard = document.getElementById('perf-dashboard');
if (dashboard) {
dashboard.innerHTML = `
<div>Page Load: ${this.metrics.pageLoad.toFixed(2)}ms</div>
<div>Memory: ${Math.round(this.metrics.memoryUsage / 1024 / 1024)}MB</div>
<div>Errors: ${this.metrics.errors}</div>
<div>API Calls: ${this.metrics.apiCalls}</div>
`;
}
}
}