Skip to content

How to Measure Web Vitals

Key idea:

Core Web Vitals 2026: LCP (Largest Contentful Paint) < 2.5s, INP (Interaction to Next Paint, replaced FID March 2024) < 200ms, CLS (Cumulative Layout Shift) < 0.1. Field data (real users) — critical for SEO. Lab data (Lighthouse) for testing. Tools: web-vitals.js, Google CrUX, Search Console, Vercel Speed Insights, Enterno RUM.

Below: step-by-step, working examples, common pitfalls, FAQ.

Try it now — free →

Step-by-Step Setup

  1. Install npm install web-vitals
  2. Report on all 4 metrics in JS
  3. POST beacon to your analytics endpoint
  4. Aggregate p75 (75-percentile — Google threshold)
  5. Dashboard: filter by page, device, country
  6. Alert: p75 LCP > 2.5s on critical pages
  7. Cross-reference with Google Search Console CrUX data

Working Examples

ScenarioConfig
Basic web-vitals reportingimport { onCLS, onINP, onLCP, onFCP, onTTFB } from 'web-vitals'; function sendToAnalytics(metric) { const body = JSON.stringify(metric); fetch('/api/vitals', { method: 'POST', body, keepalive: true }); } onCLS(sendToAnalytics); onINP(sendToAnalytics); onLCP(sendToAnalytics);
Enterno RUM beacon<!-- Add to <head> --> <script src="https://enterno.io/rum/beacon.js" data-site="my-site" defer></script> <!-- Automatically collects CWV, sends to Enterno RUM dashboard -->
Vercel Speed Insights# Next.js import { SpeedInsights } from '@vercel/speed-insights/next'; export default function RootLayout({ children }) { return ( <html> <body> {children} <SpeedInsights /> </body> </html> ); }
Fix slow LCP<!-- Preload LCP image --> <link rel="preload" as="image" href="/hero.webp" fetchpriority="high"> <!-- Lazy-load below-fold --> <img src="/hero.webp" fetchpriority="high"> <!-- LCP candidate --> <img src="/below.webp" loading="lazy">
Fix CLS/* Reserve space for images */ .hero-img { aspect-ratio: 16 / 9; width: 100%; } <!-- Or explicit size --> <img src="hero.webp" width="1600" height="900" alt="...">

Common Pitfalls

  • Only lab data (Lighthouse) — misses real-world slow devices. Field data from RUM essential
  • INP replaces FID — old implementations still track FID. Update to web-vitals v3+
  • p75 aggregate — not p50 (median hides slow tail). Google uses p75
  • RUM overhead: beacon.js ~2 KB + send overhead. Use keepalive + sendBeacon API
  • Privacy: do not send user_id in vitals. Aggregate without PII
PerformanceOverall speed score 0-100
Core Web VitalsLCP, FID, CLS — Google metrics
Page SizeSize of HTML, CSS, JS, images
RecommendationsSpecific tips for improvement

Why teams trust us

Lighthouse
analysis engine
CWV
Core Web Vitals
4
Lighthouse categories
Precise
recommendations

How it works

1

Enter page URL

2

Lighthouse analyzes

3

Get CWV scores & tips

Why Does Site Speed Matter?

Page load speed directly impacts conversion, SEO rankings, and user satisfaction. Google uses Core Web Vitals as a ranking factor. Every extra second of load time cancost up to 7% in conversions.

Lighthouse Analysis

Google Lighthouse-based analysis: Performance, Accessibility, Best Practices, SEO.

Core Web Vitals

LCP (rendering), FID (interactivity), CLS (visual stability) — key Google metrics.

Resource Analysis

Breakdown by type: HTML, CSS, JavaScript, images, fonts. Size, request count, blocking resources.

Actionable Advice

Specific recommendations with savings estimates: image compression, caching, minification, etc.

Mobile vs Desktop

Mobile
  • Tested on Moto G Power emulation (slow CPU)
  • Network: 4G (1.6 Mbps, 150ms RTT)
  • Stricter speed scoring
  • Google indexes mobile-first
  • Priority for SEO optimization
Desktop
  • High CPU performance
  • Fast connection without throttling
  • Scores typically 20-40 points higher
  • Important for B2B and corporate sites
  • Use for baseline comparisons

Who uses this

SEO

Core Web Vitals for rankings

Developers

performance optimization

Marketers

speed = conversions

DevOps

performance regression

Common Mistakes

Unoptimized imagesImages can be up to 70% of page weight. Use WebP/AVIF and lazy loading.
Render-blocking JS in &lt;head&gt;Scripts without async/defer block rendering. Move to end or add attribute.
No static asset cachingWithout Cache-Control, the browser reloads CSS/JS on every visit.
Too many HTTP requestsEach request adds latency. Bundle files, use sprites, or inline critical CSS.
Missing compression (gzip/brotli)Compression reduces text resource size by 60-80%. Enable brotli on the server.

Best Practices

Optimize imagesWebP for photos, SVG for icons. loading="lazy" for images below the fold.
Enable brotli compressionBrotli is 15-20% more efficient than gzip. Configure in nginx: brotli on;
Set up cachingStatic: Cache-Control: max-age=31536000, immutable. HTML: max-age=0, s-maxage=60.
Preload critical resources<link rel="preload"> for fonts and CSS. Reduces LCP by 200-500ms.
Test regularlySpeed degrades over time. Check after each deploy and monthly.

Get more with a free account

Speed check history, competitor comparison and PageSpeed monitoring.

Sign up free

Learn more

Frequently Asked Questions

Field vs Lab data?

Field (CrUX, RUM): real users, slow devices, varied networks. Lab (Lighthouse): synthetic ideal conditions. Google SEO = field data.

Why did INP replace FID?

FID = first interaction (usually fast). INP = worst interaction per session → better UX signal. March 2024 migration.

RUM provider?

<a href="/en/rum">Enterno RUM</a> (free tier + pro), Vercel Speed Insights ($10/mo), Google CrUX (free but aggregated), SpeedCurve ($20+).

Check without install?

<a href="/en/speed">Enterno PageSpeed</a> for lab scores. Google PageSpeed Insights — shows CrUX field data.