GoogleChrome / web-vitals

Essential metrics for a healthy site.
https://web.dev/vitals
Apache License 2.0
7.47k stars 410 forks source link

Missing Cumulative Layout Shift (CLS) metric when batching multiple reports together in a single network request #500

Closed eduardvalentin0007 closed 2 months ago

eduardvalentin0007 commented 2 months ago

Hello everyone,

After upgrading the web-vital plugin from 3.5.2 to 4.1.1, we noticed a problem with the Cumulative Layout Shift (CLS) metric. We are seeing a rapid decrease in about 99% of the CLS counts.

Our implementation is very similar to your recommendation batch-multiple-reports-together, so we report all available metrics when the page is in the background or unloaded (document.visibilityState === 'hidden').

But if we compare the file src/lib/onHidden.ts in versions (3.5.2 and 4.1.1), we can see that we used to use the pagehide or visibilitychange event (event.type === 'pagehide' || document.visibilityState === 'hidden') and now only the visibilitychange event.

Our current problem now is that the flushQueue() visibilitychange listener in js is called earlier than the visibilitychange listener from src/lib/onHidden.ts, and unfortunately it is too late to pass the cls metrics.

Is there a workaround to get all the Web Vitals metrics and then call the flushQueue() function?

Thanks in advance. Vasili and Edu

philipwalton commented 2 months ago

Our implementation is very similar to your recommendation batch-multiple-reports-together, so we report all available metrics when the page is in the background or unloaded (document.visibilityState === 'hidden').

Try updating your implementation to not use pagehide and just use visibilitychange. We should update the snippet in the README to match the logic in the library.

Note that all of the bugs that used to require pagehide in addition to visibilitychange have now been fixed, so pagehide is not really needed anymore.

philipwalton commented 2 months ago

Updated the README in #501.

eduardvalentin0007 commented 2 months ago

Thank you for your reply.

We are currently utilizing the visibilitychange implementation exclusively to invoke the flushQueue() function.

I believe this is due to both the visibilitychange event listener from src/lib/onHidden.ts for cls metrics and our js file utilizing the same event.

The intriguing question would be: How can I ensure that the listener in src/lib/onHidden.ts is triggered before the one in the js file?

mikep-dev commented 2 months ago

I haven't noticed your issue when I was posting a very similar one here https://github.com/GoogleChrome/web-vitals/issues/502 Long story short, you are probably attaching your event listener to document which might lead to issues with order of execution. Try to use window.addEventListener or addEventListener instead.

eduardvalentin0007 commented 2 months ago

This was exactly our problem. After switching to window.addEventListener, the CLS metric is now being collected on time.

Thanks for your support!