Core Web Vitals
Measure real-world user experience for loading performance, interactivity, and visual stability with LCP, INP, CLS, TTFB and FCP metrics.
Core Web Vitals are a set of metrics defined by Google that measure real-world user experience for loading performance, interactivity, and visual stability. These metrics directly impact SEO rankings and user satisfaction. AbrovaTrace uses Google's official web-vitals library for accurate measurement.
Web Vitals are browser-specific metrics. Today only the Next.js SDK (@abrova-trace/nextjs-sdk) reports them. For mobile apps (iOS, Android, Flutter), use API Latency Tracking instead.
Metrics Explained#
LCP — Largest Contentful Paint
Measures loading performance. Marks when the largest content element (image, video, or text block) becomes visible.
INP — Interaction to Next Paint
Measures overall responsiveness. Observes all interactions and reports the worst latency.
CLS — Cumulative Layout Shift
Measures visual stability. Sum of all unexpected layout shifts during the page's lifecycle.
TTFB
Time to First Byte
Server response time
Good: ≤800ms
FCP
First Contentful Paint
Perceived load speed
Good: ≤1.8s
Next.js#
Basic Setup
import { AbrovaTrace } from '@abrova-trace/nextjs-sdk';
AbrovaTrace.init({
apiKey: 'ab_live_your_api_key',
environment: 'production',
release: '1.0.0',
});
// Enable Web Vitals tracking
// Automatically captures LCP, INP, CLS, TTFB, FCP
AbrovaTrace.getInstance()?.enableWebVitals();App Router (Next.js 13+)
// app/providers.tsx
'use client';
import { useEffect } from 'react';
import { AbrovaTrace } from '@abrova-trace/nextjs-sdk';
export function Providers({ children }: { children: React.ReactNode }) {
useEffect(() => {
AbrovaTrace.init({
apiKey: process.env.NEXT_PUBLIC_ABROVA_TRACE_KEY!,
environment: process.env.NODE_ENV,
});
// Enable Web Vitals tracking
AbrovaTrace.getInstance()?.enableWebVitals();
// Enable HTTP performance tracking
AbrovaTrace.getInstance()?.enablePerformanceTracking();
return () => AbrovaTrace.getInstance()?.close();
}, []);
return <>{children}</>;
}Pages Router
// pages/_app.tsx
import { useEffect } from 'react';
import { AbrovaTrace } from '@abrova-trace/nextjs-sdk';
function MyApp({ Component, pageProps }) {
useEffect(() => {
AbrovaTrace.init({
apiKey: process.env.NEXT_PUBLIC_ABROVA_TRACE_KEY!,
environment: process.env.NODE_ENV,
});
AbrovaTrace.getInstance()?.enableWebVitals();
AbrovaTrace.getInstance()?.enablePerformanceTracking();
return () => AbrovaTrace.getInstance()?.close();
}, []);
return <Component {...pageProps} />;
}
export default MyApp;Advanced Options
// Report all metric changes (not just final values)
AbrovaTrace.getInstance()?.enableWebVitals({
reportAllChanges: true,
});
// Custom batch interval (default: 5000ms): vitals are sent this long after
// the last metric arrives, and also when the page is hidden or unloaded
AbrovaTrace.getInstance()?.enableWebVitals({
batchInterval: 10000, // 10 seconds
});Data Structure#
Web Vitals data is reported with the following structure:
interface WebVitalsData {
pageUrl: string; // Full page URL
pageRoute?: string; // Route path (e.g., /dashboard)
// Core Web Vitals
lcpMs?: number; // Largest Contentful Paint
cls?: number; // Cumulative Layout Shift
inpMs?: number; // Interaction to Next Paint
ttfbMs?: number; // Time to First Byte
fcpMs?: number; // First Contentful Paint
// Context
deviceType?: string; // 'mobile' | 'tablet' | 'desktop'
connectionType?: string; // from Navigator API (4g, 3g, etc.)
sessionId?: string; // Per page-load ID from the Web Vitals tracker (not getSessionId())
platform: 'nextjs';
environment?: string; // production, staging
releaseVersion?: string; // App version
}Dashboard View#
In Abrova Console, Abrova Trace → Performance shows Web Vitals in a dedicated card: the 75th percentile (p75) of each metric over the selected period, rated Good / Needs improvement / Poor with the thresholds above.
Core Web Vitals Card
Improving Your Scores#
Improve LCP
- • Optimize and compress images
- • Use a CDN for static assets
- • Preload critical resources
- • Minimize render-blocking JavaScript
Improve INP
- • Break up long JavaScript tasks
- • Use web workers for heavy computation
- • Optimize event handlers
- • Defer non-critical JavaScript
Improve CLS
- • Always include size attributes on images
- • Reserve space for dynamic content
- • Avoid inserting content above existing content
- • Use transform animations instead of layout changes
Best Practices#
Enable Web Vitals tracking as early as possible in your app lifecycle for accurate measurements
Web Vitals are most meaningful from real production users — development data may be skewed
Track Web Vitals per route/page to identify which pages need optimization
Use the dashboard trends to see how deployments affect performance
INP is the Core Web Vital for interactivity — prioritize improving responsiveness
Aim for "Good" thresholds on 75th percentile of page loads