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

feat: add attributions for core web vitals: LCP, CLS, and FID #432

Merged
merged 4 commits into from
Sep 11, 2023

Conversation

williazz
Copy link
Contributor

@williazz williazz commented Aug 15, 2023

Revision 1

  1. Collect attributions for LCP, FID, and CLS
  2. Only some fields are captured, ignoring those that are redundant or not relevant for diagnostics

Revision 2

  • Remove attribution double check
  • Integ test for browser support. Checks that attributions exist for LCP and CLS. FID cannot be tested because the web vitals package ignores programmatically triggered input.

Will be included in another PR

  1. Link CWV attributes to their related Resource and Navigation events
  2. Integ test for FID, if possible

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@williazz williazz changed the base branch from main to release/2.0.x August 18, 2023 18:30
@williazz williazz force-pushed the CWVAttributions branch 4 times, most recently from 40cf75b to 2d52a51 Compare August 23, 2023 17:49
@williazz williazz marked this pull request as ready for review August 23, 2023 18:08
| FirstInputDelayEvent
| CumulativeLayoutShiftEvent = {
protected onload(): void {
onLCP((metric) => this.handleLCP(metric));
Copy link
Contributor Author

@williazz williazz Aug 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requires arrow function to preserve reference of keyword this so that context can still be found

onCLS((metric) => this.handleCLS(metric));
}

handleLCP(metric: LCPMetricWithAttribution | Metric) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will never expect any of these handlers to receive just Metric because we are using the attribution build of web-vitals. However, they left Metric in as an argument type, so we should still double check that attributions are attached

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: Why do we need to double check that attributions are attached?

Looking at the type definition, it should always be LCPMetricWithAttribution, although TypeScript does think it could be Metric at this point. If we know it will always be LCPMetricWithAttribution then we can simplify this logic.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was my initial thought as well, but I was spooked into double checking because because TypeScript was complaining, like you said. I'm happy to make that change though

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed double check

@qhanam
Copy link
Member

qhanam commented Aug 24, 2023

issue: I think we should create browser integ tests for web vital attribution, especially considering different browsers support different features related to the collection of web vitals.

onCLS,
onFID,
onLCP
} from 'web-vitals/attribution';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: By how much does using the web-vitals attribution build (+ adding our own code to record attribution) increase the total size of the compressed aws-rum-web package?

At some point we will also want to create different builds, of different sizes, for aws-rum-web.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not do an exact comparison. There was no documentation on size difference in the web vitals package for different builds, so I just did my best to keep my changes as small as possible.

I can check though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used the bundle analyzer plugin to do a size comparison. I compared parsed sizes of the cwr.js, WebVitalsPlugin, and web-vitals package.

release/2.0.x

  • total size = 212.76kb
  • web vitals plugin = 1.24kb
  • web-vitals package = 6.52kb

this pr

  • total size = 215.82kb
  • web vitals plugin = 9.56kb
  • web-vitals package = 2.02kb

diff

  • total size = + ~3kb
  • web vitals plugins = + ~8kb
  • web vitals package = -4kb?

Not sure why the attributions build is smaller than the normal build.

src/plugins/event-plugins/WebVitalsPlugin.ts Outdated Show resolved Hide resolved
onCLS((metric) => this.handleCLS(metric));
}

handleLCP(metric: LCPMetricWithAttribution | Metric) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: Why do we need to double check that attributions are attached?

Looking at the type definition, it should always be LCPMetricWithAttribution, although TypeScript does think it could be Metric at this point. If we know it will always be LCPMetricWithAttribution then we can simplify this logic.

@williazz
Copy link
Contributor Author

williazz commented Aug 24, 2023

issue: I think we should create browser integ tests for web vital attribution, especially considering different browsers support different features related to the collection of web vitals.

Currently looking into this. If the scope is big enough, it may have to be a separate PR @qhanam

Update:

Added integ test for attribution for LCP and CLS on chrome. FID is supported on Chrome, Firefox (and Safari + IE via polyfill). However, FID cannot be tested on testcafe because the web vitals package knows to ignore manually triggered user input.

https://github.com/GoogleChrome/web-vitals#browser-support

@@ -52,7 +64,7 @@ describe('WebVitalsPlugin tests', () => {
record.mockClear();
});

test('When web vitals are present then events are recorded', async () => {
test('When web vitals are present then LCP is recorded with attributions', async () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: Do we need unit tests to cover case where attributions could not be collected?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we need "when [web vital] does not have attribution then event is recorded without attribution". Thanks

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correction: this test is not needed. Attributions object will always exist. Some properties are optional, such as LCP.element and all of the CLS fields. These fields will be defined as {element: undefined...} and dropped entirely during JSON.stringify().

@williazz williazz changed the base branch from release/2.0.x to main September 9, 2023 15:57
@williazz williazz merged commit 33892c5 into aws-observability:main Sep 11, 2023
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants