Core Web Vitals
These metrics have become the standard for measuring user experience in 2025:
- LCP (Largest Contentful Paint): Measures loading performance - should occur within 2.5 seconds
- INP (Interaction to Next Paint): Replaced FID in 2024 - measures responsiveness to user interactions, should be under 200ms
- CLS (Cumulative Layout Shift): Measures visual stability - should be less than 0.1
- TTFB (Time To First Byte): Initial server response time - should be under 800ms for good UX
Essential Optimizations for Static Sites
-
Image Optimization
- Use modern formats: WebP and AVIF with fallbacks
- Implement responsive images with
srcsetandsizes - Lazy load images below the fold with
loading="lazy" - Consider the new native image CDN solutions available in 2025
-
Font Optimization
- Use system font stacks where possible
- For custom fonts, use
font-display: swapand preload critical fonts - Consider variable fonts for multiple weights/styles
- Subset fonts to include only needed characters
-
CSS Optimization
- Place critical CSS inline in the
<head> - Defer non-critical CSS
- Use modern CSS features like container queries and cascade layers
- Consider the new CSS nesting features standardized in 2024
- Place critical CSS inline in the
-
JavaScript Optimization
- Only include what you need - small sites often need minimal JS
- Use ES modules with
type="module"for better code splitting - Defer non-critical JavaScript with
deferattribute - Consider no-JS fallbacks for core functionality
Measurement Tools for 2025
- Lighthouse in Chrome DevTools: Still the standard for performance auditing
- PageSpeed Insights: Combines lab and field data
- web-vitals library: For in-app performance monitoring
- Chrome User Experience Report: For real-world performance data
Monitoring Web Vitals in Production
Even for small static sites, it's valuable to collect real-user performance metrics using the web-vitals library:
// Import from skypack CDN for zero-setup use
import {
onCLS,
onFID,
onLCP,
onTTFB,
onINP
} from 'https://cdn.skypack.dev/web-vitals';
function sendToAnalytics(metric) {
// Use your analytics provider's API or a simple endpoint
const body = JSON.stringify({
name: metric.name,
value: metric.value,
id: metric.id,
delta: metric.delta
});
// Use the Beacon API when available
if (navigator.sendBeacon) {
navigator.sendBeacon('/analytics', body);
} else {
fetch('/analytics', {
body,
method: 'POST',
keepalive: true
});
}
}
// Monitor the Core Web Vitals
onCLS(sendToAnalytics);
onFID(sendToAnalytics);
onLCP(sendToAnalytics);
onTTFB(sendToAnalytics);
onINP(sendToAnalytics); // The new responsiveness metric for 2024/2025