What Are Core Web Vitals?

Core Web Vitals are a set of three performance metrics defined by Google that measure real-world user experience on web pages. They directly impact search rankings and represent what Google considers the most important aspects of page experience.

As a QA engineer, understanding these metrics is essential because:

  • They affect SEO rankings (search visibility)
  • They correlate with user engagement and conversion rates
  • They provide objective, measurable criteria for performance acceptance testing
  • They are increasingly included in performance budgets and release criteria

The Three Core Web Vitals

LCP — Largest Contentful Paint

What it measures: The time from when the page starts loading to when the largest content element in the viewport is rendered.

Good threshold: Under 2.5 seconds

What counts as the “largest element”:

  • Images (<img>, <image> inside SVG)
  • Video poster images
  • Background images loaded via url()
  • Block-level text elements (<h1>, <p>, etc.)
gantt title LCP Timeline dateFormat X axisFormat %s section Loading TTFB :0, 800 Resource Load :800, 1500 LCP Element :1500, 2200 section Thresholds Good (<2.5s) :0, 2500 Needs Work :2500, 4000 Poor (>4s) :4000, 5000

Common causes of poor LCP:

  • Slow server response time (high TTFB)
  • Render-blocking JavaScript and CSS
  • Slow resource load times (large images, unoptimized fonts)
  • Client-side rendering delays (SPA frameworks)

INP — Interaction to Next Paint

What it measures: The responsiveness of the page to user interactions (clicks, taps, key presses) throughout its entire lifecycle. INP is the worst interaction latency, ignoring outliers.

Good threshold: Under 200 milliseconds

How it works:

  1. User clicks a button
  2. Browser processes the event handler (JavaScript)
  3. Browser updates the visual display
  4. INP measures the total time from step 1 to step 3

Common causes of poor INP:

  • Long-running JavaScript tasks blocking the main thread
  • Excessive DOM size (>1500 elements)
  • Complex event handlers without optimization
  • Third-party scripts competing for main thread time

CLS — Cumulative Layout Shift

What it measures: The total of all unexpected layout shifts that occur during the entire lifespan of the page. A layout shift happens when a visible element changes its position from one frame to the next without user interaction.

Good threshold: Under 0.1

CLS calculation:

Layout Shift Score = Impact Fraction × Distance Fraction
  • Impact fraction: The area of the viewport affected by the shift
  • Distance fraction: How far the element moved relative to the viewport

Common causes of poor CLS:

  • Images and ads without explicit width/height dimensions
  • Dynamically injected content above existing content
  • Web fonts causing text to resize (FOIT/FOUT)
  • Late-loading third-party embeds

Measuring Core Web Vitals

Lab Data (Development/Testing)

Lab data is collected in a controlled environment. It is reproducible but does not represent real-user conditions.

ToolLCPINPCLSNotes
Chrome DevTools (Performance tab)YesYesYesMost detailed
LighthouseYesNo (uses TBT)YesAggregate scores
PageSpeed InsightsYesYesYesLab + field data
WebPageTestYesPartialYesMulti-location testing

Field Data (Real Users)

Field data comes from actual users visiting your site. It reflects real conditions but requires traffic volume.

SourceData TypeAvailability
Chrome UX Report (CrUX)28-day rolling averagePublic (sites with enough traffic)
PageSpeed InsightsCrUX data with origin summaryPublic
Search ConsoleCore Web Vitals reportSite owners only
web-vitals JavaScript libraryReal-time per-user dataRequires implementation

Using DevTools Performance Tab

  1. Open DevTools > Performance tab
  2. Click the gear icon and enable Web Vitals
  3. Click Record and reload the page
  4. Stop recording after the page fully loads
  5. Look for the Web Vitals lane showing LCP, CLS markers
  6. The Summary pane shows timing breakdowns

Quick Check with PageSpeed Insights

Navigate to pagespeed.web.dev and enter your URL. The report shows:

  • Field data (if available): Real-user Core Web Vitals from the past 28 days
  • Lab data: Simulated performance from a mid-tier mobile device on 4G
  • Diagnostics: Specific issues with recommended fixes
  • Passed audits: What is already working well

Testing Strategies for Core Web Vitals

LCP Testing Checklist

  • Measure LCP on the landing page, product pages, and blog posts
  • Test with throttled network (Slow 3G, Fast 3G, 4G)
  • Test with CPU throttling (4x, 6x slowdown)
  • Verify LCP element is the intended hero image/text, not an unexpected element
  • Check that LCP does not regress after new deployments
  • Test with empty cache and primed cache

INP Testing Checklist

  • Click every interactive element and note if any feel sluggish
  • Test form submissions, dropdown menus, and modal openings
  • Test while the page is still loading (partially loaded state)
  • Use DevTools Performance tab to identify long tasks (>50ms)
  • Test with CPU throttling to simulate lower-end devices

CLS Testing Checklist

  • Watch the page load from start to finish — note any visual jumps
  • Scroll through the entire page watching for shifts
  • Test with slow network to see layout shifts during progressive loading
  • Verify all images have explicit width and height attributes
  • Test with ad blockers disabled (ads are a common CLS source)
  • Check font loading — does text reflow when web fonts load?

Exercise: Core Web Vitals Audit

Perform a Core Web Vitals audit on a website of your choice (your company’s site, a personal project, or a well-known public site).

Step 1: Collect Lab Data

Open the site in Chrome with DevTools:

  1. Go to the Performance tab
  2. Enable Web Vitals in settings
  3. Set throttling: CPU 4x slowdown, Fast 3G network
  4. Record a fresh page load (clear cache first with Ctrl+Shift+Delete)
  5. Record the following values:
MetricValueGood ThresholdPass/Fail
LCP___s<2.5s
CLS___<0.1
TBT (proxy for INP)___ms<200ms

Step 2: Identify LCP Element

In the Performance recording:

  1. Find the LCP marker in the Web Vitals lane
  2. Click on it to see which element triggered LCP
  3. Document: What is the LCP element? Is it the intended hero content?

Step 3: Find Layout Shifts

  1. In the Performance recording, look for pink bars in the Experience row
  2. Click each layout shift to see which elements moved
  3. Document each shift: What element? How far did it move? What caused it?

Step 4: Test Interactions

  1. Record a new performance session
  2. Click on 5-10 interactive elements (buttons, links, menus, form fields)
  3. Look for long tasks (yellow blocks >50ms) triggered by your interactions
  4. Document any interaction that takes more than 200ms to respond visually
Solution: Sample Audit Report

Site audited: example-ecommerce.com (homepage)

Lab Results (Chrome, CPU 4x, Fast 3G):

MetricValueThresholdStatus
LCP3.8s<2.5sFAIL
CLS0.24<0.1FAIL
TBT890ms<200msFAIL

LCP Analysis:

  • LCP element: Hero banner image (2.4MB JPEG)
  • Root cause: Image is not optimized, no responsive srcset, no preload hint
  • Fix: Convert to WebP, add loading="eager", add <link rel="preload">, implement srcset for responsive sizes

CLS Issues Found:

ElementShift ScoreCause
Hero image0.12No width/height attributes
Ad banner0.08Injected after page load
Cookie consent0.04Pushes content down
  • Fix: Add explicit dimensions to images, reserve space for ads with CSS, use overlay for cookie consent instead of pushing content

INP/TBT Issues:

  • Main thread blocked for 450ms by analytics bundle
  • Product carousel initialization blocks for 320ms
  • Third-party chat widget adds 120ms to page load
  • Fix: Defer analytics, lazy-load carousel, load chat widget on user interaction

Recommendations priority:

  1. Optimize hero image (LCP: expected improvement from 3.8s to ~1.8s)
  2. Add image dimensions (CLS: expected improvement from 0.24 to ~0.04)
  3. Defer non-critical JavaScript (TBT: expected improvement from 890ms to ~200ms)

Automated Core Web Vitals Monitoring

For ongoing quality assurance, integrate Core Web Vitals into your CI/CD pipeline:

# Using Lighthouse CI
npm install -g @lhci/cli

# Run Lighthouse with assertions
lhci autorun --config=lighthouserc.json

Example lighthouserc.json with Core Web Vitals thresholds:

{
  "ci": {
    "assert": {
      "assertions": {
        "largest-contentful-paint": ["error", {"maxNumericValue": 2500}],
        "cumulative-layout-shift": ["error", {"maxNumericValue": 0.1}],
        "total-blocking-time": ["error", {"maxNumericValue": 200}]
      }
    }
  }
}

This fails the build if Core Web Vitals exceed thresholds, preventing performance regressions from reaching production.

Key Takeaways

  • Core Web Vitals consist of three metrics: LCP (loading), INP (interactivity), and CLS (visual stability)
  • INP replaced FID in March 2024 and measures responsiveness across the entire page lifecycle
  • Use both lab data (DevTools, Lighthouse) and field data (CrUX, Search Console) for a complete picture
  • Each metric has specific testing strategies — do not just check the aggregate score
  • Integrate Core Web Vitals thresholds into CI/CD to prevent regressions
  • Poor Core Web Vitals directly impact SEO rankings and user engagement