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

Add missing parsing time #541

Merged
merged 6 commits into from
Apr 2, 2024
Merged

Add missing parsing time #541

merged 6 commits into from
Apr 2, 2024

Conversation

codecapitano
Copy link
Collaborator

@codecapitano codecapitano commented Mar 28, 2024

Why

When comparing page-load time with time spent in the browser, let's say dom and render timings + response time, there is notable delta between the sum of the latter timings and page-load time.

After some investigation, the results are:

Faro is working correct and we derive all timings as they should be, but why the delta?

We did some manual math and it turns out that the delta is mostly related to the time the browser needs to parse the document.

IMG_5973

So the plan is calculate parser time as well.

How to calculate the parser time

Unfortunately the current performance timeline doesn't provide and event to retrospectively get the timestamp when the parser is starting it's work. In the image below you can see that we have responseEnd followed by domInteractive.
One could argue that we simply can use domInteractive - responseEnd, but this can not be used because the browser may start parsing even before the last bit of the response has arrived.

image

When reading the docs for domInteractive we see that this property represents the time immediately before the documents ready state is set to "interactive"

The domInteractive read-only property returns a DOMHighResTimeStamp representing the time immediately before the user agent sets the document's readyState to "interactive". ——MDN

So let's have a look if we can utilize the documents readyState to get that timestamp.
Turns out: yes, but!

When the parsers start it's work thedocument.readyState property changes to 'loading' (see mdn Document: readyState property).

This could be a suitable strategy in case we fetch the readyState at the beginning of the <head> of the index.html file.
But this is not working for us because we can't control when Faro is initialized. Some user may defer loading and so on.
Also we need a good mechanism to ensure that fetching the readyState is done before everything else.
Another option would be to put this work on the user side and have user adding extra logic specific to enable use fetching that timestamp. Even if we provide copy&paste code this is no option and very error prone because people will likely forget to do that.

image

PerformanceTiming: domLoading property to the rescue

The old, deprecated, performance.timing object provides the domLoading property which is moment when the parser is starting its work.

The legacy PerformanceTiming.domLoading read-only property returns an unsigned long long representing the moment, in milliseconds since the UNIX epoch, when the parser started its work, that is when its Document.readyState changes to 'loading' and the corresponding readystatechange event is thrown. ——MDN

performance.timing.domLoading is deprecated but still supported in all browsers.

Deprecated: This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the compatibility table at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time.

According to the w3 docs for domLoading the reason for the deprecation is:

The domLoading attribute is deprecated and may be removed in future versions of this specification. Due to differences in when a Document object is created in existing user agents, the value returned by the domLoading is implementation specific and should not be used in meaningful metrics.——W3 Docs

Solution

The domLoading property can be used to calculate the parser time.

image

Even if the metric is different across user agents I still see value in providing the information and close the gap in numbers mentioned above.

One downside is that we are using a deprecated API, so we need to:

  • ensure to not break Faro in case a browser vendor removes it
  • keep an eye on browser api updates to react early
  • keep researching a better solution

What

  • Calculate parser time by using the domLoading property

Links

Checklist

  • Tests added
  • Changelog updated
  • Documentation updated

Copy link
Collaborator

@kpelelis kpelelis left a comment

Choose a reason for hiding this comment

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

Short questions but overall this is very well written! 🪨

@codecapitano codecapitano merged commit 7622096 into main Apr 2, 2024
2 checks passed
@codecapitano codecapitano deleted the add-missing-parsingTime branch April 2, 2024 09:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants