Web development
Core Web Vitals: reproducible protocol, evidence and counter-tests
Evidence before score
Measure the population, diagnose the session, never merge the two.
- 3 metrics kept separate
- 4 evidence states
- 8 decision gates
- 0 ranking guarantees
Short answer
Core Web Vitals measure real experience in the field; lab tools explain one controlled run.
LCP, INP and CLS are three different distributions, not one speed score. A field assessment describes the 75th percentile of eligible experiences. A lab run describes a device, network, page state and scenario. When CrUX, RUM, Lighthouse and a trace disagree, do not average them. Name the population, isolate the metric, locate the responsible element or interaction, correct one cause and counter-test under comparable conditions.
This guide publishes the complete decision contract, an open bilingual dataset and a browser instrument that records this session locally. It deliberately refuses three shortcuts: TBT is not renamed INP; missing CrUX data is not treated as a pass; a faster laboratory run is not presented as ranking or revenue causality.
01 · Metric contract
LCP ≤ 2.5 s, INP ≤ 200 ms and CLS ≤ 0.1 only mean “good” with a population and percentile.
The stable Core Web Vitals are Largest Contentful Paint, Interaction to Next Paint and Cumulative Layout Shift. Google’s public thresholds classify a page or origin as “good” when at least 75% of eligible experiences meet the threshold. That sentence carries the essential information: the value is a distribution, not the best run, not the average and not the desktop score displayed in a report.
| Metric | Good | Needs improvement | Poor | Question |
|---|---|---|---|---|
| LCP | ≤ 2,500 ms | > 2,500 to 4,000 ms | > 4,000 ms | When does the main content become visible? |
| INP | ≤ 200 ms | > 200 to 500 ms | > 500 ms | How long does the page take to visibly react? |
| CLS | ≤ 0.1 | > 0.1 to 0.25 | > 0.25 | How much unexpected movement accumulates? |
Do not merge
A page can have good LCP and poor INP. An origin can pass globally while a strategic template fails. Mobile and desktop can diverge. Each distribution keeps its own population and diagnosis.
02 · Evidence hierarchy
CrUX, first-party RUM, Lighthouse and a trace answer four different questions.
| Layer | What it observes | Use it to | Never infer |
|---|---|---|---|
| CrUX | Eligible Chrome experiences over a rolling 28-day window | Establish a public field distribution by URL or origin when available | The exact cause, every browser or today’s release |
| First-party RUM | Instrumented real sessions under a published collection policy | Segment templates, devices, releases and diagnostic attribution | Unobserved users or unbiased coverage without evidence |
| Lighthouse / lab | One controlled simulation and its synthetic trace | Reproduce a defect, inspect causes and counter-test a change | A field pass rate, official INP or business uplift |
| Performance trace | Elements, resources, tasks, interactions and frames in one execution | Assign a symptom to a candidate cause | Population prevalence or causal impact from one run |
A disagreement is not a data-quality failure by default. Lighthouse may expose a cold-load problem that is diluted among returning field users. CrUX may reveal slow interactions that a load-only test never exercises. RUM may expose a checkout template hidden by an origin-wide aggregate. The method therefore preserves every layer and its timestamp instead of electing a single “true score”.
If CrUX has insufficient data, record “not measured”. Low traffic, a new URL or insufficient eligible Chrome visits can explain the absence. None proves a good experience. This distinction is especially important for a young B2B site: a green lab test is useful operational evidence, but it cannot stand in for a field population that does not exist yet.
03 · Decision protocol
Eight gates turn a red metric into a correction that can be counter-tested.
The gates are ordered. They prevent the most frequent category errors before optimisation begins: changing an image because “performance is red”, replacing a library because TBT is high, or announcing a Core Web Vitals pass after one Lighthouse run. A release may continue with an open field status; it may not silently turn that unknown into success.
CWV-G01
Qualify
Source, population, window and percentile are named before the verdict.
CWV-G02
Separate
A lab value is never presented as a CrUX or RUM value.
CWV-G03
Decompose
Missing CrUX data remains ‘not measured’, never ‘passing’.
CWV-G04
Attribute
Each slow metric is decomposed before a correction is chosen.
CWV-G05
Hypothesise
The responsible element or interaction is retained in the evidence.
CWV-G06
Correct
The counter-test replays the same scenario, device, viewport, network and method version.
CWV-G07
Counter-test
A lab improvement does not become business causality or a ranking guarantee.
CWV-G08
Validate
Field validation waits for an explicitly sufficient window and volume.
04 · LCP attribution
Diagnose LCP as four intervals and retain the actual candidate element.
LCP is not synonymous with image weight. Start with the element reported by the trace. It may be a hero image, a poster, a text block or a background. Then break its timestamp into four parts: time to first byte, delay before the resource starts, resource-load duration and delay between resource completion and rendering.
High TTFB points towards origin work, cache misses, redirects or network distance. High resource-load delay points towards late discovery, CSS backgrounds, client rendering or priority competition. High load duration points towards bytes, compression, connection and origin delivery. High render delay points towards hidden content, fonts, main-thread work or a resource that loaded before the element could be painted.
This decomposition avoids contradictory fixes. Preloading cannot repair a slow origin. Re-encoding a 20 KB image cannot repair a one-second render delay. A faster image may even leave LCP unchanged when the text baseline remains the largest candidate.
lcp = ttfb
resourceLoadDelay
resourceLoadDuration
elementRenderDelayKeep the selector, current resource URL, timing parts, viewport and page state in the proof. A number without its candidate is not an actionable LCP diagnosis.
05 · INP attribution
Separate input delay, processing and presentation before blaming JavaScript.
INP begins with a real interaction. Its latency contains the wait before handlers run, the time spent executing them and the delay until the next frame is presented. A slow click can therefore come from earlier work blocking the main thread, expensive application logic, synchronous layout, a large render or several causes at once.
Exercise the critical journeys: open navigation, expand the FAQ, submit invalid and valid form states, play media, use search and trigger the main CTA. Record the interaction target and page state. Long Animation Frames can connect the slow interval to long frames and scripts when the browser supports the API. Unsupported attribution remains unsupported; it is not converted into a pass.
The local lab below reports the worst interaction observed in the session. It does not claim the official INP of a field population. The official metric applies interaction selection and aggregation rules across real visits; the local value is a diagnostic candidate for a controlled replay.
interactionLatency = inputDelay
processingDuration
presentationDelay06 · CLS attribution
A CLS score needs shifted elements, session windows and a timeline.
CLS accumulates unexpected layout shifts in session windows. The useful evidence is not only the total: it includes the moment, value, shifted nodes and preceding action. Shifts caused within the recent-input exclusion window are treated differently, which is why clicking an accordion and seeing content move does not automatically create a CLS defect.
Frequent causes include media without reserved geometry, ads or embeds injected above content, fonts that alter metrics, notices inserted after first paint and animations that change layout properties. Reserve the final space, keep responsive aspect ratios truthful, choose compatible font fallbacks and animate transforms rather than layout where appropriate.
Test the entire lifecycle. A page may be stable during loading and shift when a consent message, audio player, validation summary or lazy component appears. A screenshot cannot prove stability; the sequence and sources can.
07 · Executable proof
Arm a clean navigation, exercise the page and export the evidence.
Arm the next navigation. The page reloads from the top and starts observing automatically, before you open the table of contents, expand FAQ items, activate an article action or play the audio when available. Freeze the proof only after the scenario is complete. The export records the capture mode, environment, supported APIs, candidates, timing parts, element geometry, visibility changes and explicit limitations. It excludes form values and the proof never leaves the browser.
The first visit remains opt-in and starts no observer. Only the explicit arming action triggers one page reload; the versioned module then reads buffered navigation entries and begins the session without a second user input. The URL marker is immediately removed without another request. This prevents a late click or restored scroll position from being mistaken for a clean navigation measurement.
Interactive instrument · v1.2
CWV Evidence Lab · measure this session locally
Your first action arms a clean navigation. The page reloads from the top and observation starts automatically. A compact control stays available during the scenario: it freezes the observers before returning you to this proof.
- 01Start
- 02Exercise
- 03Freeze
- 04Reuse
Lab statusReady to arm a clean navigation
API support
- PerformanceObserver
- —
Evidence detail
Not observed
Compare two proofs
The comparison is rejected when method, path, browser family, DPR or viewport are not comparable. Declared scenario and navigation transfer state must also match.
One explicit page reload · local execution · no cookie · no proof transmission · no text-field value collected. The downloaded file contains the user agent, platform and viewport: review it before sharing.
Interpretation boundary
The export is a session proof. It can support a diagnosis and a same-condition counter-test. It cannot certify the origin, reproduce CrUX, establish conversion impact or prove that the observed delta was caused by one code change.
08 · Edikka self-audit
The public baseline is a dated lab result; field status remains “not measured”.
| Evidence | Observed | Status | What it permits |
|---|---|---|---|
| Lighthouse performance | 100 / 100 | Lab diagnostic | Describe one simulated execution |
| LCP | 1,594.54 ms | Lab diagnostic | Counter-test the rewritten page under the same profile |
| CLS | 0.0065228 | Lab diagnostic | Inspect the simulated load sequence |
| TBT | 0 ms | Lab diagnostic | Describe blocking during that load; not INP |
| CrUX / first-party RUM | No dataset published | Not measured | No field verdict |
The run used Lighthouse 9.6.8 with a mobile Moto G (4) emulation and Headless Chrome 155. It transferred 158,995 bytes over 16 requests. These values are published because they are reproducible context, not because they prove current field quality. The run predates this rewritten edition, and a future counter-test must keep that chronology visible.
The SEO subscore was 93 because that Lighthouse version did not recognise Edikka’s Content-signal directive. The performance observation and the SEO parser warning are separate findings; neither should be hidden inside the overall score. No PageSpeed API field result is claimed because a valid CrUX response was not obtained during this review.
Four Safari and Firefox exports exposed a method defect; none qualified as a counter-test.
| Browser | Exports | Observed APIs | Unavailable APIs | Comparison verdict |
|---|---|---|---|---|
| Safari | 2 | LCP, Event Timing | Layout Shift, LoAF, soft navigation | Rejected: scenario absent; mixed transfer states; one load-only file contains a pointer interaction |
| Firefox | 2 | LCP, Event Timing | Layout Shift, LoAF, soft navigation | Rejected: scenario absent; mixed transfer states |
The four v1.1 files were useful evidence, not valid before/after pairs. Their filenames claimed “load-only” or “interactive”, but the proof itself encoded neither the scenario nor its completion. Each same-browser pair also mixed one network transfer with one zero-transfer navigation. One supposed load-only Safari export even contained a pointer interaction after navigation.
This failure produced version 1.2: scenario, completion, page-input count and navigation transfer state are now machine-verifiable comparison gates. Only derived counts are published here; raw user-agent strings are not republished.
Published negative
The current evidence cannot establish INP or a Core Web Vitals field pass for Edikka. The honest result is “not measured”, even though the laboratory load is fast.
09 · Release contract
A performance budget prevents regressions; it does not replace field validation.
CI should protect deterministic properties: asset budgets, missing image dimensions, unexpected third-party requests, duplicate preloads, long tasks in a named journey and lab deltas beyond an agreed tolerance. Store the trace and environment when a gate fails. Do not make an origin-wide CrUX percentile a per-commit gate: the 28-day field window cannot identify one commit in real time.
A useful release record therefore has two clocks. The fast loop runs trace and laboratory counter-tests before deployment. The slow loop watches RUM or CrUX after deployment and waits for an adequate population and window. If traffic is low, report raw eligible counts and retain “insufficient data” rather than optimising the threshold until it turns green.
Fast loop
Before release
- Same URL and scenario
- Fixed browser and viewport
- Trace retained
- One cause changed
- Lab delta reported
Slow loop
After release
- Eligible population named
- Raw volume retained
- 75th percentile by metric
- Release annotation kept
- Unknown remains unknown
10 · Editorial boundary
This page owns measurement and attribution, not every performance optimisation.
Use the web-image optimisation protocol for codecs, responsive sources, perceptual quality and delivery. Use the technical SEO audit protocol for crawling, canonicals, rendering and broader technical controls. Use the business-impact analysis to frame commercial risk without turning a lab delta into attributed revenue.
This division prevents cannibalisation and keeps every claim with the evidence it needs. Core Web Vitals are the measurement and diagnostic interface between those territories, not a synonym for all front-end quality.
11 · Open resources
Download, replay, challenge and cite version 1.2.
How to cite
Morel, Bertrand (2026). Core Web Vitals: reproducible protocol, evidence and counter-tests. Edikka, version 1.2, CC BY 4.0.
Permanent identifier: none declared. A DOI will only be added after deposit.
Next review: 4 December 2026. Corrections remain in the public changelog.
Public changelog
| Version | Date | Change |
|---|---|---|
| 1.2 | 4 September 2026 | Declared load-only or interactive scenario, privacy-preserving event markers, scenario completion, instrument-input exclusion and navigation transfer-state comparability. |
| 1.1 | 4 September 2026 | Armed clean navigation, automatic observer start, explicit missing/API states, LCP element geometry and stricter proof comparability. |
| 1.0 | 4 September 2026 | Initial protocol, public baseline and local evidence instrument. |
Primary sources and their exact role
- Google Search Central · Core Web Vitals — Metric status and relationship with Google Search.
- Google Search Central · Page experience — Signal scope and absence of a ranking guarantee.
- web.dev · Defining Core Web Vitals thresholds — Thresholds and 75th-percentile aggregation.
- web.dev · Lab and field data differences — Differences in population, environment and purpose.
- web.dev · Optimize LCP — Diagnostic LCP breakdown.
- web.dev · Optimize INP — Interaction breakdown and diagnostic paths.
- web.dev · Optimize CLS — Session windows and layout-shift causes.
- web.dev · Debug performance in the field — Field attribution and web-vitals instrumentation.
- Chrome for Developers · CrUX API — CrUX data availability and querying.
- Chrome for Developers · Long Animation Frames API — Long-frame attribution around slow interactions.
- GoogleChrome · web-vitals changelog — Library evolution and soft-navigation support.
A green score is not the goal. A decision that survives a counter-test is.
Keep field truth, lab diagnosis and technical attribution separate. Performance work becomes credible when the evidence can say “not measured”.
Name the population
A percentile without users, window and source is a detached number.
Keep the responsible object
An element, interaction, resource or frame turns a symptom into a hypothesis.
Change one cause
Comparable conditions make the delta useful; only the field can validate the population.
Measure without confusing field and lab data
Ten answers aligned with the thresholds, attribution, counter-tests and explicit limits of the Edikka protocol.