Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inflated LCP View timing when visibility change occurs during page load #1256

Closed
dvndrsn opened this issue Jan 7, 2022 · 9 comments
Closed
Labels
bug Something isn't working rum

Comments

@dvndrsn
Copy link

dvndrsn commented Jan 7, 2022

DataDog Browser SDK with Real User Metrics (RUM) can potentially record inflated Largest Contentful Paint (LCP) values when a visibility change occurs during page load. When a user opens a long-loading website and then switches tabs, causing the original page to no longer be visible, PerformanceObserver will not report the LCP timing until the user switches back to the original tab (when the painting occurs).

The GoogleChrome/web-vitals reference implementation correctly ignores the LCP entries generated when the user switches back to the original tab if the page was not visible as it was loaded. The DataDog RUM client, however, does not ignore LCP entries that are generated when the tab is refocused. Inflated LCP values are passed through and reported to DataDog.

Both GoogleChrome/web-vitals and DataDog RUM correctly ignore LCP entries generated for pages that are opened and loaded entirely in the background (no visibility state change during load - always hidden).

There are ongoing discussions referencing this challenge in properly logging LCP in other libraries.

w3c/paint-timing#40
newrelic/newrelic-browser-agent#70

Here is the relevant section of the GoogleChrome/web-vitals implementation that ignores LCP events generated when the browser window is hidden:

https://github.com/GoogleChrome/web-vitals/blob/main/src/getLCP.ts#L40
https://github.com/GoogleChrome/web-vitals/blob/main/src/lib/getVisibilityWatcher.ts#L28
https://github.com/GoogleChrome/web-vitals/blob/main/src/lib/onHidden.ts#L33

Is there a workaround on the client side to avoid logging these inflated values or is a fix possible on the DataDog SDK side?

@ixjamesyoo
Copy link

ixjamesyoo commented Jan 7, 2022

Screen recording of the issue reported by my teammate @dvndrsn
https://youtu.be/STHsRMj5-bg


Additional context - code snippets for the console.logs in the video:

  • PerformanceObserver
    <script>
      try {
        let lcp;

        const po = new PerformanceObserver(entryList => {
          const entries = entryList.getEntries();
          const lastEntry = entries[entries.length - 1];

          // Update `lcp` to the latest value, using `renderTime` if it's available,
          // otherwise using `loadTime`. (Note: `renderTime` may not be available on
          // image elements loaded cross-origin without the `Timing-Allow-Origin` header.)
          lcp = lastEntry.renderTime || lastEntry.loadTime;
          console.log(
            'performance observer LCP:',
            lastEntry.renderTime ? lastEntry : lastEntry.loadTime,
          );
        });

        po.observe({ type: 'largest-contentful-paint', buffered: true });
      } catch (e) {
        // Do nothing if the browser doesn't support this API.
      }
    </script>
  • Datadog RUM
 DD_RUM.init({
           // ...
            beforeSend: (e, ctx) => {
              if (e.view.largest_contentful_paint) {
                console.log('DD LCP timing', e.view.largest_contentful_paint / 10 ** 9);
              }
            },
          });
  • GoogleChrome/web-vitals
    <script type="module">
      import { getLCP } from 'https://unpkg.com/web-vitals?module';

      getLCP(foo => console.log('web vitals - LCP timing', foo));
    </script>

@vanderhoop
Copy link

For what it's worth, NewRelic appears to be aligning around the web-vitals approach as well, though I can't say whether their change would address the very specific case shown in the video above.

@bcaudan bcaudan added bug Something isn't working rum labels Jan 10, 2022
@bcaudan
Copy link
Contributor

bcaudan commented Jan 10, 2022

Hello,

Thanks for raising this, we will look into it shortly.

@BenoitZugmeyer
Copy link
Member

Hello, thanks for the thorough bug report! The Datadog RUM Browser SDK should indeed behave like the web-vitals reference implementation.

It seems that you are calling getLCP from an inline script, could you confirm that it's the same for DD_RUM.init? Or is DD_RUM.init called after a bit (ex: during onload)? Are you using the trackViewsManually option?

@BenoitZugmeyer
Copy link
Member

Nevermind, I found an obvious issue: #1259

@BenoitZugmeyer
Copy link
Member

Thanks again for the report. The mentioned PR should have fixed the issue. We'll make a release soon, probably tomorrow. Let us know if you still see something strange!

@ixjamesyoo
Copy link

Thanks for the quick response! We'll keep an eye out for the release

@vanderhoop
Copy link

vanderhoop commented Jan 10, 2022

Hey @BenoitZugmeyer, will this change be included in the 3.X series, or just 4.X? (We're currently in 3.X, delivered via CDN)

@BenoitZugmeyer
Copy link
Member

I released the fix as part of v4.1.0. It won't be backported to 3.x as we don't usually maintain anterior versions. I encourage you to update to v4!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working rum
Projects
None yet
Development

No branches or pull requests

5 participants