seo-core-web-vitals
Dedicated Core Web Vitals deep-dive: pull field data (CrUX / PageSpeed Insights), fall back to Lighthouse lab data, score LCP, INP, and CLS against Google's thresholds at the 75th percentile, and run
Files1
View on GitHubSKILL.mdskills/seo-core-web-vitals/SKILL.md
GitHubCore Web Vitals Deep-Dive
<!-- Updated: 2026-06-10 -->Core Web Vitals (CWV) measure real-world loading performance, responsiveness, and visual stability. Google's position, per https://developers.google.com/search/docs/appearance/core-web-vitals: CWV are used by Google's core ranking systems and good CWV is recommended for success with Search — but good scores alone do not guarantee top rankings; there is more to page experience than CWV, and chasing a perfect score purely for SEO is not the best use of time.
INP replaced FID on March 12, 2024. FID is gone from all Chrome tooling. Never reference FID as a current metric.
Thresholds
Each metric is evaluated at the 75th percentile of real page loads, segmented by mobile and desktop. A page "passes" CWV when all three metrics are Good at p75.
| Metric | Measures | Good | Needs Improvement | Poor |
|---|---|---|---|---|
| LCP (Largest Contentful Paint) | Loading | ≤ 2.5s | 2.5s – 4.0s | > 4.0s |
| INP (Interaction to Next Paint) | Responsiveness | ≤ 200ms | 200ms – 500ms | > 500ms |
| CLS (Cumulative Layout Shift) | Visual stability | ≤ 0.1 | 0.1 – 0.25 | > 0.25 |
References: https://web.dev/articles/lcp · https://web.dev/articles/inp · https://web.dev/articles/cls · https://web.dev/articles/vitals
Inputs
| Input | Required | Notes |
|---|---|---|
| URL or origin | Yes | URL-level data preferred; origin-level as fallback |
| Form factor | No | Default: report both mobile (PHONE) and desktop |
| CrUX API key | No | Degrade to PSI API if absent |
Execution
Field data — CrUX API (preferred, needs an API key):
curl -s -X POST "https://chromeuxreport.googleapis.com/v1/records:queryRecord?key=$CRUX_API_KEY" \ -H 'Content-Type: application/json' \ -d '{"url": "<url>", "formFactor": "PHONE", "metrics": ["largest_contentful_paint","interaction_to_next_paint","cumulative_layout_shift"]}'Docs: https://developer.chrome.com/docs/crux/api
- If the URL has insufficient traffic (404 response), retry with
"origin"instead of"url"and note that results are origin-level. - No API key? Degrade gracefully to step 2 — do not fail.
- If the URL has insufficient traffic (404 response), retry with
Field data — PageSpeed Insights API (no key needed for light use):
curl -s "https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=<url>&category=performance&strategy=mobile"CrUX field data is embedded in
loadingExperience(URL-level) andoriginLoadingExperience(origin-level): p75 percentiles and Good/NI/Poor distributions per metric. Docs: https://developers.google.com/speed/docs/insights/v5/get-startedLab fallback / diagnostics — Lighthouse. If no field data exists (low-traffic page), use the
lighthouseResultfrom step 2 or theseo-lighthouse-auditskill. Label it clearly as lab data: lab LCP/CLS approximate field values; lab has no INP — use TBT (Total Blocking Time) as a rough proxy for interactivity problems, never as a substitute score.Score each metric against the thresholds table (Good / Needs Improvement / Poor at p75, mobile and desktop separately). Mobile is usually worse — lead with it.
Diagnose failing metrics using the playbooks below, fetching the page HTML (
curl -s <url>) to check for concrete causes (missingfetchpriority, unsized images, render-blocking tags, heavy third-party scripts).
Diagnosis Playbooks
LCP — break into the four subparts
| Subpart | Typical share | Fixes |
|---|---|---|
| TTFB (server time to first byte) | ~40% | CDN, edge caching, faster origin, Server-Timing header to locate backend cost, avoid redirect chains |
| Resource load delay (gap before LCP resource starts downloading) | should be ~0 | <link rel="preload"> the LCP image/font, fetchpriority="high" on the LCP <img>, never loading="lazy" on the LCP element, avoid CSS background-image for hero |
| Resource load time (download duration) | varies | Compress/resize image, modern formats (WebP/AVIF), CDN, preconnect to the resource origin |
| Element render delay (downloaded but not painted) | should be small | Eliminate render-blocking CSS/JS, inline critical CSS, avoid client-side rendering of the hero |
Full guide: https://web.dev/articles/optimize-lcp · Lighthouse LCP audit
INP — find the slow interaction
Common causes and fixes:
- Long tasks on the main thread — break work into <50ms chunks, yield with
scheduler.yield()/setTimeout; see Lighthouse TBT audit - Heavy event handlers — debounce, move computation to Web Workers, defer non-visual work until after the next paint
- Large DOM — keep under ~1,500 nodes; big DOMs make style/layout recalc slow on every interaction (dom-size audit)
- Third-party JS — tag managers, ads, chat widgets competing for the main thread; lazy-load or facade them (third-party-summary)
- Excessive hydration (SPA frameworks) — partial/progressive hydration, server components
Full guide: https://web.dev/articles/optimize-inp
CLS — find what moved
Common causes and fixes:
- Unsized images/embeds/iframes — always set
width/heightor CSSaspect-ratioso the browser reserves space - Injected content (ads, banners, late-loading UI) — reserve slots with fixed min-height; never insert above existing content except on user interaction
- Web fonts (FOIT/FOUT swaps) —
font-display: swapplussize-adjust/fallback font metric matching; preload critical fonts (font-display audit) - Animations using layout properties — animate
transforminstead oftop/left/width/height
Full guide: https://web.dev/articles/optimize-cls
Output
# Core Web Vitals Report: <url>
## Field Data (CrUX, 75th percentile, last 28 days)
| Metric | Mobile p75 | Desktop p75 | Rating (mobile) |
|--------|-----------|-------------|-----------------|
| LCP | X.Xs | X.Xs | ✅ Good / ⚠️ NI / ❌ Poor |
| INP | XXXms | XXXms | ✅/⚠️/❌ |
| CLS | 0.XX | 0.XX | ✅/⚠️/❌ |
CWV Assessment: PASS / FAIL (all three Good at p75 → pass)
Data level: URL / Origin (note if origin-level fallback was used)
## Distribution (per metric)
Good XX% | Needs Improvement XX% | Poor XX%
## Lab Data (Lighthouse — diagnostics only)
LCP X.Xs · TBT XXXms (INP proxy, not a substitute) · CLS 0.XX
## Diagnosis & Fixes (per failing metric)
### LCP (if failing): subpart breakdown + top 3 fixes
### INP (if failing): suspected cause + top 3 fixes
### CLS (if failing): shifting elements + top 3 fixes
## Context
- CWV is used by Google's ranking systems, but good CWV alone does not
guarantee rankings — see
https://developers.google.com/search/docs/appearance/core-web-vitals
- For the broader experience checklist (HTTPS, interstitials, mobile),
see the seo-page-experience skill.