📋 Table of Contents
Web PerformanceMonitoring
Comprehensive guide to web performance monitoring – metrics, tools, and best practices for optimal website performance and better user experience. Performance monitoring is essential for modern web applications, providing insights into load times, user interactions, and Core Web Vitals. Professional web performance monitoring helps identify bottlenecks and continuously improve user experience. Learn how to use performance monitoring tools and which metrics are critical for your business.
🚀 What is Web Performance Monitoring?
Web Performance Monitoring (WPM) is the continuous process of monitoring, measuring, and analyzing the speed and availability of a website or web application. The goal is to ensure optimal user experience and achieve business objectives.
- Real-time monitoring: Continuous measurement of website performance
- Problem detection: Early identification of performance issues
- User experience: Improved user experience through optimized load times
- Business impact: Direct effect on conversion rates and ROI
⚡ Core Web Vitals
Core Web Vitals are Google's key metrics for user experience:
LCP
Largest Contentful Paint
Target: < 2.5s
FID
First Input Delay
Target: < 100ms
CLS
Cumulative Layout Shift
Target: < 0.1
// Measure Core Web Vitals with Web Vitals Library
import { getCLS, getFID, getFCP, getLCP, getTTFB } from 'web-vitals';
getCLS(console.log);
getFID(console.log);
getFCP(console.log);
getLCP(console.log);
getTTFB(console.log);
// Performance Observer API
const observer = new PerformanceObserver((list) => {
list.getEntries().forEach((entry) => {
if (entry.entryType === 'largest-contentful-paint') {
console.log('LCP:', entry.startTime);
}
});
});
observer.observe({ type: 'largest-contentful-paint', buffered: true });
📊 Key Performance Metrics
Load Time Metrics
TTFB (Time to First Byte)
Time until the first byte from the server
Target: < 200ms
FCP (First Contentful Paint)
First visible content
Target: < 1.8s
Speed Index
Speed of visual rendering
Target: < 3.4s
TTI (Time to Interactive)
Time until fully interactive
Target: < 3.8s
🛠️ Monitoring Tools & Techniques
Browser-based Tools
- Chrome DevTools: Performance Tab, Lighthouse, Network Tab
- Firefox Developer Tools: Performance Panel, Network Monitor
- Edge DevTools: Performance Profiler, Issues Tab
Online Testing Services
// PageSpeed Insights API
const PSI_API_KEY = 'your-api-key';
const url = 'https://example.com';
const response = await fetch(
`https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=${url}&key=${PSI_API_KEY}`
);
const data = await response.json();
console.log('Performance Score:', data.lighthouseResult.categories.performance.score * 100);
console.log('LCP:', data.lighthouseResult.audits['largest-contentful-paint'].displayValue);
Enterprise Monitoring Solutions
Real User Monitoring (RUM)
- • Google Analytics 4
- • New Relic Browser
- • Datadog RUM
- • Sentry Performance
Synthetic Monitoring
- • Pingdom
- • GTmetrix
- • WebPageTest
- • Lighthouse CI
🔄 RUM vs. Synthetic Monitoring
Real User Monitoring (RUM)
- ✅ Real user data
- ✅ Various devices & networks
- ✅ Geographic distribution
- ❌ Reactive (after problems occur)
- ❌ Requires traffic
Synthetic Monitoring
- ✅ Proactive monitoring
- ✅ Controlled conditions
- ✅ Works without traffic
- ❌ Simulated environment
- ❌ Limited real-world accuracy
⚙️ Implementation & Best Practices
Performance Monitoring Setup
// Custom Performance Monitoring
class PerformanceMonitor {
constructor() {
this.metrics = {};
this.setupObservers();
}
setupObservers() {
// Navigation Timing
window.addEventListener('load', () => {
const navigation = performance.getEntriesByType('navigation')[0];
this.metrics.pageLoadTime = navigation.loadEventEnd - navigation.navigationStart;
this.metrics.domContentLoaded = navigation.domContentLoadedEventEnd - navigation.navigationStart;
this.metrics.ttfb = navigation.responseStart - navigation.navigationStart;
});
// Performance Observer für Web Vitals
const observer = new PerformanceObserver((list) => {
list.getEntries().forEach(entry => {
switch (entry.entryType) {
case 'largest-contentful-paint':
this.metrics.lcp = entry.startTime;
break;
case 'first-input':
this.metrics.fid = entry.processingStart - entry.startTime;
break;
case 'layout-shift':
if (!entry.hadRecentInput) {
this.metrics.cls = (this.metrics.cls || 0) + entry.value;
}
break;
}
});
});
observer.observe({
type: 'largest-contentful-paint',
buffered: true
});
observer.observe({
type: 'first-input',
buffered: true
});
observer.observe({
type: 'layout-shift',
buffered: true
});
}
sendMetrics() {
// An Analytics-Service senden
fetch('/api/performance', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
...this.metrics,
url: window.location.href,
userAgent: navigator.userAgent,
timestamp: Date.now()
})
});
}
}
// Initialisierung
const monitor = new PerformanceMonitor();
window.addEventListener('beforeunload', () => monitor.sendMetrics());
💰 Performance Budgets
Performance budgets define clear limits for key metrics and help prevent performance regressions.
// lighthouse-budget.json
{
"path": "/*",
"timings": [
{
"metric": "first-contentful-paint",
"budget": 2000
},
{
"metric": "largest-contentful-paint",
"budget": 2500
},
{
"metric": "speed-index",
"budget": 3000
}
],
"resourceSizes": [
{
"resourceType": "script",
"budget": 300
},
{
"resourceType": "image",
"budget": 500
},
{
"resourceType": "total",
"budget": 1000
}
]
}
🎯 Optimization Strategies
Frontend Optimizations
- Code Splitting: Load only necessary code
- Lazy Loading: Load images and components on demand
- Resource Hints: dns-prefetch, preconnect, prefetch
- Caching: Use browser cache and service workers
- Minification: Minify CSS, JS, and HTML
Backend Optimizations
- CDN: Content Delivery Network for static assets
- Compression: Gzip/Brotli for text content
- Database Optimization: Optimize queries and indexes
- Server Response Time: Keep TTFB under 200ms
- HTTP/2 & HTTP/3: Use modern protocols
💡 Practical Examples
Next.js Performance Monitoring
// pages/_app.js - Next.js Web Vitals Reporting
export function reportWebVitals(metric) {
const { id, name, label, value } = metric;
// An Analytics-Service senden
gtag('event', name, {
event_category: label === 'web-vital' ? 'Web Vitals' : 'Next.js custom metric',
value: Math.round(name === 'CLS' ? value * 1000 : value),
event_label: id,
non_interaction: true,
});
// Oder an eigenen Service
fetch('/api/analytics', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
metric: name,
value,
label,
id,
url: window.location.href
})
});
}
// Lighthouse CI Integration
// .lighthouserc.js
module.exports = {
ci: {
collect: {
url: ['http://localhost:3000'],
numberOfRuns: 3,
},
assert: {
assertions: {
'categories:performance': ['error', { minScore: 0.9 }],
'categories:accessibility': ['error', { minScore: 0.9 }],
'categories:best-practices': ['error', { minScore: 0.9 }],
'categories:seo': ['error', { minScore: 0.9 }],
},
},
upload: {
target: 'lhci',
serverBaseUrl: 'https://your-lhci-server.com',
},
},
};