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

fix: Record resource timing after load event #450

Merged
merged 7 commits into from
Sep 19, 2023

Conversation

qhanam
Copy link
Member

@qhanam qhanam commented Sep 15, 2023

The web client does not currently record PerformanceResource entries after the load event fires. This means that slow, asynchronous resources, that contribute to poor web vitals like LCP or CLS, will not be recorded.

This change modifies the PerformanceResource plugin to continue listening to PerformanceResource entries after the load event.

To accomplish this, we modify our resource prioritization in the following ways:

  1. We always record entries for document, scripts, stylesheets and fonts (was previously capped).
  2. We record entries for everything else (including images) up to the configured limit.

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

@@ -132,6 +114,12 @@ export class ResourcePlugin extends InternalPlugin {
};

protected onload(): void {
window.addEventListener(LOAD, this.resourceEventListener);
// We need to set `buffered: true`, so the observer also records past
Copy link
Contributor

Choose a reason for hiding this comment

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

Question: are will still concerned about using performance.geEntries() as backup for browsers that do not support PerformanceObserver?

Copy link
Contributor

Choose a reason for hiding this comment

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

}
});
}
list.filter((e) => e.entryType === RESOURCE)
Copy link
Contributor

@williazz williazz Sep 15, 2023

Choose a reason for hiding this comment

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

question: aren't these already filtered?

performanceObserver.observe({type: 'resource'...})

);

await t.expect(events.length).eql(1);
});

test('when resource loads after window.load then the resource is recorded', async (t: TestController) => {
test('when resource loads before the plugin then the resource is recorded', async (t: TestController) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Question: When does window.load occur during TestCafe test? Why did reversing these fix the problem?

Copy link
Member Author

Choose a reason for hiding this comment

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

Firefox seems caching the image between runs, so during the second run it doesn't make a request to the server for it.

I assume there is some Firefox (or TestCafe) configuration that prevents this caching.

Copy link
Contributor

Choose a reason for hiding this comment

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

Switched the tests in #448 like you did here

@williazz
Copy link
Contributor

williazz commented Sep 15, 2023

I agree with the implementation. Only blocking thing for me to understand how you fixed that resource plugin integration test

@qhanam qhanam requested a review from ps863 September 15, 2023 16:18
]
ResourceType.FONT
],
sampleTypes: [ResourceType.IMAGE, ResourceType.OTHER]
Copy link
Contributor

Choose a reason for hiding this comment

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

Question: Why are images not included? This may impact lcp attribution. I remember you considered recording all types

Copy link
Contributor

Choose a reason for hiding this comment

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

nevermind

list.filter((e) => e.entryType === RESOURCE)
.filter((e) => !this.config.ignore(e))
.forEach((event) => {
const type: ResourceType = getResourceFileType(event.name);
Copy link
Contributor

@williazz williazz Sep 19, 2023

Choose a reason for hiding this comment

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

Issue: I have found that sometimes event.name does not include the correct file type extension. This can cause getResourceFileType to fail. Could we add logic to use initatorType as a backup method to verify this information?

Copy link
Contributor

@williazz williazz Sep 19, 2023

Choose a reason for hiding this comment

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

I had to do the same check here in #448

link

Copy link
Member Author

Choose a reason for hiding this comment

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

I agree using initiatorType sounds like a good idea to get more accurate resource types. That is, instead of using only the file extension to identify the resource type,getResourceFileType would also use initiatorType.

I believe this is a new feature though. In #448, could you also use getResourceFileType? Then we can make a separate PR to improve getResourceFileType accuracy by considering initatorType.

@qhanam qhanam merged commit c0aa33a into aws-observability:main Sep 19, 2023
3 checks passed
@qhanam qhanam deleted the fix-resources-after-load branch September 19, 2023 19:08
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.

None yet

3 participants