Search code examples
vue.jsvuejs2single-page-applicationcore-web-vitalsweb-vitals

How to collect Core Web Vitals for SPA Vue application


I'm looking to start collecting Core Web Vitals for a Single Page Application (SPA) website. It's a Vue 2 application that uses vue-router. I've been playing around with using web-vitals to collect the vitals and sending the results via Google Analytics events.

I realized after trying to collect vitals on every single page/view that there are some issues with collecting vitals on SPAs. Namely, that web-vitals doesn't handle soft navigations as one might hope. This is discussed in the Web Vital Metrics for Single Page Applications GitHub issue.

It seems like it wouldn't work to collect page-level web vitals for an SPA, at least not in the way that I mention above. But would there be any value in just inserting web-vitals (onCLS, onFID, onLCP) in the App.vue file to get some high level results for a single session? Or would the resulting values be completely off and meaningless?

What is a good solution to automatically collecting web vitals for an SPA?


Solution

  • Currently the Core Web Vitals collected by the browser do not account for SPA navigations (sometimes known as soft navigations). The metrics are collected based on a full, browser navigation.

    But would there be any value in just inserting web-vitals (onCLS, onFID, onLCP) in the App.vue file to get some high level results for a single session? Or would the resulting values be completely off and meaningless?

    If you did try to collect this on each SPA route change, it would mean the following:

    LCP would not be emitted as the LCP timing is finalised on click (which presumably is what triggers the soft navigation)

    From the LCP docs:

    The browser will stop reporting new entries as soon as the user interacts with the page (via a tap, scroll, or keypress), as user interaction often changes what's visible to the user (which is especially true with scrolling).

    This means it will basically always report the LCP of the first page.

    CLS will be be calculated based on the largest window across the full browser navigation

    This means it will report the largest CLS window whether that is on the first page, or a subsequent one.

    FID will only be reported on the first interaction

    Similar to LCP, this is likely to be the interaction that caused the first soft navigation.

    So yes, just measuring them on each soft navigation will result in basically incorrect or meaningless numbers being reported. Not to mention that web-vitals will not emit these metrics in most cases.

    What is a good solution to automatically collecting web vitals for an SPA?

    There is an experiment in Chrome currently under way (including an experimental branch of web-vitals), which allows you to tell the browser to reset these metrics on each soft navigation to allow you to measure these properly. We're actively looking for feedback on how well this works and what should be changed before this goes live.