Chrome 151’s Soft Navigations API finally lets single-page apps (SPAs) report Core Web Vitals for every in-app navigation, but Google’s CrUX dataset still only records the first hard load, leaving developers with two divergent performance pictures.

Why SPA metrics have lagged

Core Web Vitals—Largest Contentful Paint (LCP), Interaction-to-Next-Paint (INP) and Cumulative Layout Shift (CLS)—were defined around hard navigations. A hard navigation fetches a brand-new document and discards the previous page’s state.

SPAs built with React, Vue, Next.js, or similar frameworks rarely trigger hard navigations. Clicking a link updates the URL via the History API, fetches data in the background, and swaps content without a full reload. The existing Performance API only captures the initial page load, so LCP and INP never see the latency users feel when they move from one route to another.

That blind spot skews dashboards that pull data from the Performance Timeline or Google’s Chrome User Experience Report (CrUX). They often show an excellent LCP for the “shell” page while ignoring slower loads deeper in the app, giving a false sense of performance health.

Chrome’s Soft Navigations API

Chrome 151 introduced the Soft Navigations API, a set of heuristics that treats certain SPA interactions as real navigations. The API watches for three signals:

  • A user-initiated interaction (click, tap, keyboard event)
  • A URL change via the History API
  • Subsequent paint events that render new content

When all three line up, Chrome logs a soft navigation in the Performance Timeline, and Core Web Vitals are calculated for that transition just like for a hard navigation. The open-source web-vitals library added support on July 21, so developers can start pulling these numbers with the same API they already use.

In practice, you now see an LCP value for each route change, an INP that reflects the true latency of the last user input, and a CLS that captures layout shifts after a soft navigation.

The data split: Chrome vs. CrUX

Google’s CrUX (Chrome User Experience Report) powers PageSpeed Insights, Search Console and, indirectly, ranking signals. CrUX still aggregates only hard-navigation data.

Consequently, you end up with two consistent but different data streams:

  • Internal tools that read the Performance Timeline now show route-level LCP, INP and CLS, giving a realistic view of what users experience in a SPA.
  • Google’s public datasets continue to show metrics for the first page load only, which is what Search Console reports and what Google’s ranking algorithms reference.

Both are correct; they just measure different moments. Relying solely on Search Console can mask performance regressions that happen after the initial load, while internal dashboards alone won’t reflect the baseline that Google uses for SEO.

What developers need to watch

  • Browser support – The Soft Navigations API lives only in Chromium-based browsers today. Safari and Firefox lack an equivalent, so you must keep fallback logic for a portion of your audience.
  • Heuristic limits – The API decides a soft navigation based on a set of cues. If your app updates content without changing the URL (e.g., modal overlays or infinite scroll), the API may miss those transitions, leaving gaps in the data.
  • Testing before trusting – Because detection is heuristic, run a suite of real-world interactions on your app and compare the reported metrics against manual timing (e.g., using performance.mark). Only after confirming accuracy should you base optimisation decisions on the new numbers.

Bottom line

Chrome 151 gives SPA developers the long-awaited ability to measure LCP, INP and CLS for every in-app route change, but Google’s ranking data still reflects only the first hard load. Until CrUX catches up, teams must juggle two parallel data sets: one that tells the true user story, and another that drives search rankings. Balancing both—and preparing for broader browser support—will be key to maintaining performance-first SPAs in a competitive web ecosystem.