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

The sourceLocation property of PerformanceScriptTiming is complex or ambiguous to parse #6

Closed
philipwalton opened this issue Jan 30, 2024 · 0 comments · Fixed by w3c/longtasks#136
Assignees

Comments

@philipwalton
Copy link
Member

Context

The PerformanceScriptTiming interface exposes a sourceLocation property, which contains the following three bits of information concatenated together as a single string:

`${source_function_name}@${source_URL}:${source_character_position}`

All three of these bits are useful, but in some cases a developer may want to extract individual bits out separately in order to group or aggregate multiple PerformanceScriptTiming instances together. For example, to calculate the total JS script execution or blocking time by script URL or origin (e.g. something that RUMvision has experimented with).

Problem

In order to be able to extract the function name, URL, and character position data from the sourceLocation property, a developer needs to properly parse the sourceLocation string and handle all of the edge cases. This is harder than it looks because some of these edge cases are non-obvious (at best) or even impossible (at worst).

Non-obvious cases:

If a developer wants to extract the source function name from the sourceLocation field, they may try to do so by checking to see if the sourceLocation field contains an @ character, and if so splitting on that character:

if (sourceLocation.includes('@') {
  const sourceFn = sourceLocation.split('@')[0];
}

However, this will fail if the sourceLocation property does not include a function name but the URL does contain an @ character. For example, the following is a perfectly valid script URL:

https://unpkg.com/package-name@1.2.3/dist/index.js

On the flip side of this, it's easy to imagine a developer writing code that is too restrictive in its matching logic and inadvertently failing to match the source function name in some cases, for example:

const sourceFn = sourceLocation.match(/^([$\w]+)@/)?.[1];

This code would match function names that use common characters like letters, numbers, and $ or _ symbols, but it wouldn't match function names with non-ASCII characters like föobãr().

And if code doesn't properly match the function name, then it will likely error if calling new URL() on a string that didn't properly remove the function name prefix.

Impossible cases:

Extracting the character position value from the sourceLocation property is less complex than extracting the function name (given that the character position value has to be a number). However, since both numeric characters as well as colon characters (:) are value URL path names, it's not possible to distinguish cases where the sourceLocation property contains character position data from cases where it doesn't but the URL happens to include those same characters. For example, the following is a perfectly valid script URL:

https://example.com/main.js:1234

If the browser was unable to expose the source character position on the above URL, it would not be possible to distinguish this URL from a the source URL main.js with a character position specified as 1234.

While this is admittedly a bit of an edge case, it is a possibility that could come up, so perhaps it's best to avoid it altogether.

Solution

To avoid all of this complexity and ambiguity, it may be easier to expose the source function, URL, and character position data on separate fields (that could be null) rather than concatenating them together.

If backwards compatibility is a concern, the API could potentially continue to expose the sourceLocation field exactly as it does today, and also expose the individual fields separately (in addition to sourceLocation).

noamr referenced this issue in w3c/longtasks Jan 31, 2024
- sourceURL (empty if not found)
- sourceFunctionName (empty if not found)
- sourceCharPosition (-1 if not found)

Closes #135
@noamr noamr transferred this issue from w3c/longtasks Mar 11, 2024
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 a pull request may close this issue.

2 participants