Monitoring
Real User Monitoring
Measuring actual user experience with RUM and Core Web Vitals
Real User Monitoring (RUM)
RUM captures and analyzes real user interactions, providing insights into actual user experience across different devices, networks, and locations.
RUM vs Synthetic Monitoring
| Aspect | RUM | Synthetic |
|---|---|---|
| Data Source | Real users | Simulated requests |
| Coverage | All user conditions | Controlled environment |
| Timing | Reactive (after issues) | Proactive (before users) |
| Cost | Scales with traffic | Fixed cost |
| Use Case | Production monitoring | Pre-release testing |
Core Web Vitals
LCP (Largest Contentful Paint)
Measures loading performance - when the main content becomes visible.
// Using web-vitals library
import { onLCP } from 'web-vitals';
onLCP((metric) => {
console.log('LCP:', metric.value);
// Send to analytics
analytics.track('web-vital', {
name: 'LCP',
value: metric.value,
rating: metric.rating, // 'good', 'needs-improvement', 'poor'
});
});Optimization targets:
- Good: < 2.5s
- Needs Improvement: 2.5s - 4.0s
- Poor: > 4.0s
INP (Interaction to Next Paint)
Measures responsiveness - delay between user interaction and visual feedback.
import { onINP } from 'web-vitals';
onINP((metric) => {
console.log('INP:', metric.value);
// Log the interaction that caused the INP
console.log('Attribution:', metric.attribution);
});Optimization targets:
- Good: < 200ms
- Needs Improvement: 200ms - 500ms
- Poor: > 500ms
CLS (Cumulative Layout Shift)
Measures visual stability - unexpected layout shifts during page load.
import { onCLS } from 'web-vitals';
onCLS((metric) => {
console.log('CLS:', metric.value);
// Log elements that shifted
metric.entries.forEach((entry) => {
console.log('Shifted element:', entry.sources);
});
});Optimization targets:
- Good: < 0.1
- Needs Improvement: 0.1 - 0.25
- Poor: > 0.25
Implementation
web-vitals Library
import { onCLS, onINP, onLCP, onFCP, onTTFB } from 'web-vitals';
function sendToAnalytics(metric) {
const body = JSON.stringify({
name: metric.name,
value: metric.value,
rating: metric.rating,
delta: metric.delta,
id: metric.id,
navigationType: metric.navigationType,
});
// Use sendBeacon for reliability
if (navigator.sendBeacon) {
navigator.sendBeacon('/analytics', body);
} else {
fetch('/analytics', { body, method: 'POST', keepalive: true });
}
}
onCLS(sendToAnalytics);
onINP(sendToAnalytics);
onLCP(sendToAnalytics);
onFCP(sendToAnalytics);
onTTFB(sendToAnalytics);Custom Performance Metrics
// Measure custom user timing
performance.mark('feature-start');
// ... feature code ...
performance.mark('feature-end');
performance.measure('feature-duration', 'feature-start', 'feature-end');
const measure = performance.getEntriesByName('feature-duration')[0];
console.log('Feature took:', measure.duration, 'ms');Session Tracking
// Track user session with context
const sessionContext = {
sessionId: generateSessionId(),
userId: getUserId(),
device: getDeviceType(),
connection: navigator.connection?.effectiveType,
viewport: `${window.innerWidth}x${window.innerHeight}`,
};
function trackMetric(metric) {
sendToAnalytics({
...metric,
...sessionContext,
timestamp: Date.now(),
url: window.location.href,
});
}Data Analysis
Percentile Analysis
Use percentiles instead of averages:
| Percentile | Use Case |
|---|---|
| P50 (Median) | Typical user experience |
| P75 | Google's Core Web Vitals threshold |
| P90 | Degraded experience |
| P99 | Worst-case scenarios |
Segmentation
Analyze metrics by:
- Device Type: Mobile vs Desktop
- Browser: Chrome, Safari, Firefox
- Geography: Region, country
- Connection: 4G, 3G, WiFi
- Page Type: Landing, product, checkout
Alerting Thresholds
| Metric | Warning | Critical |
|---|---|---|
| LCP P75 | > 2.5s | > 4.0s |
| INP P75 | > 200ms | > 500ms |
| CLS P75 | > 0.1 | > 0.25 |
| Error Rate | > 0.5% | > 1% |
| Page Load P75 | > 3s | > 5s |
Tools Integration
| Tool | Strengths |
|---|---|
| Google Analytics 4 | Free, Core Web Vitals built-in |
| Datadog RUM | Full-stack correlation |
| New Relic Browser | APM integration |
| SpeedCurve | Performance budgets |
| DebugBear | Web Vitals focus |