ANTIGRAVITY LABJP
Articles/Tips & Best Practices
Tips & Best Practices/2026-07-08Intermediate

When Lighthouse Is Green but Search Console's Core Web Vitals Are Red — Field Notes on Naming the Slow Interaction with Real-User Data

Lighthouse scores in the 90s, yet field Core Web Vitals won't budge. Here is how I closed the lab-vs-field gap with real-user monitoring (RUM), named the exact interaction driving a slow INP, and fixed it with Antigravity.

antigravity434core-web-vitalsINPRUMweb-performance

Premium Article

My Lighthouse score was 92. Green. Green every time I ran it.

And yet the Core Web Vitals report in Search Console kept INP stuck on "needs improvement." Touching it on a real device, honestly, it did not feel that slow.

As an indie developer running a small blog site on my own, this mismatch jerked me around for about two weeks. I spent that time raising the lab number, and the field number did not move a single millisecond.

The cause was simple. I had been measuring a screen that real users were not touching. This is a record of closing the lab-vs-field gap with real-user monitoring, naming the slow interaction, and only then fixing it with Antigravity.

Internalize that lab and field are different things

First I re-learned exactly what Lighthouse measures.

Lighthouse is "lab data." It is nothing more than one load, on your machine, under fixed conditions. INP in particular barely fires any interactions in the lab, so it usually comes out near zero. Of course it looks green.

Search Console, on the other hand, shows "field data": the real-user p75 from the Chrome User Experience Report (CrUX). It is the distribution of what happens when actual people press buttons, type into forms, and filter lists.

AspectLab (Lighthouse)Field (CrUX / Search Console)
What it measuresOne synthetic load28 days of real-user distribution
How it treats INPFew interactions; tends to understateReflects the p75 of real interactions
Update speedImmediateDays to weeks of lag
Used for SEO evaluationNoYes

Field data is what affects ranking. So if lab is green but field is red, the one to trust is the field. Until this sank in, I kept shooting at the wrong target.

Measure real users' INP yourself

CrUX is useful, but it is coarse and lagging. It will not tell you "which page, which interaction is slow." So I instrumented real-user monitoring (RUM) on my own site.

Google's web-vitals library has an attribution build, and that was decisive. It does not just return the INP value — it tells you the exact element and event that caused the delay.

// Collect real users' INP with its source
import { onINP } from 'web-vitals/attribution';
 
onINP((metric) => {
  const attr = metric.attribution;
  const payload = {
    value: Math.round(metric.value),          // the actual INP in ms
    rating: metric.rating,                     // good / needs-improvement / poor
    target: attr.interactionTarget,            // selector of the DOM element that caused the delay
    type: attr.interactionType,                // pointer / keyboard
    // breakdown: where the time went — input delay, processing, or presentation
    inputDelay: Math.round(attr.inputDelay),
    processingDuration: Math.round(attr.processingDuration),
    presentationDelay: Math.round(attr.presentationDelay),
    path: location.pathname,
  };
  // send lightly via beacon (survives page unload)
  navigator.sendBeacon('/api/rum', JSON.stringify(payload));
});

The interactionTarget and the three breakdown fields I send here were the treasure map. INP is the sum of input delay, processing duration, and presentation delay. Which one is fat completely changes the fix you should reach for.

I accumulated a week and aggregated by path and target. It turned out that INP p75 hit 410ms not on the homepage I had been measuring in Lighthouse, but on the tag filter of the article list. That is where most real users were interacting. I had been polishing an entrance no one walked through.

The mindset of turning measurement into continuous monitoring is the same as in Measuring Antigravity CLI startup latency with hyperfine: the starting point is holding the source of the number in your own hands.

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
Why lab (Lighthouse) and field (CrUX/RUM) diverge, and which one to trust for ranking
Using the web-vitals attribution build to pinpoint the exact DOM element and event behind a slow INP
Handing that one named interaction to Antigravity to fix, then protecting the field p75 with a regression test
Secure payment via Stripe · Cancel anytime

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Antigravity Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

Related Articles

Tips2026-07-11
Moving Antigravity to a New Machine: What Carries Over, What You Rebuild, and What Belongs in the Repo
Settings Sync restores your theme and keybindings in minutes, but auth tokens, workspace indexes, and local LLMs do not follow. A practical three-layer model for migrating Antigravity to a new machine without losing a day.
Tips2026-07-10
You Can Measure a Request Before You Send It — Sizing Agent Tasks by Working Backward from Rework Rate
When an Antigravity agent returns code that misses the mark, the cause is rarely the wording of the prompt. It is the size of the task. Here is a Python scorer that grades a request before you send it, plus what happened when I scored 80 past requests against their actual rework outcomes.
Tips2026-06-20
Keeping Scheduled Runs Reproducible: Pinning the Antigravity CLI Version to Tame Behavior Drift
The Go-based Antigravity CLI is now available to everyone, and updates are landing at a quick pace. When a CLI baked into your automation upgrades underneath you, a single morning's job can behave differently. Here is how I keep things reproducible — pinning the binary, recording its identity in each run's log, and rolling upgrades forward one job at a time — drawn from running four sites on an overnight schedule.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →