sentry-javascript
sentry-javascript copied to clipboard
feat(webvitals): Adds INP instrumentation to browserTracingIntegration
Adds an experimental enableInp
flag to v8 browserTracingIntegration, which picks up INP webvital entries from the browser and sends a span envelope containing INP data.
Some notes and changes involve:
- Adds generic span envelope types, helpers, categories, etc
- Adds
registerInpInteractionListener
, which tracks a mapping of interaction ids to the origin route names. This is used to get the route name when constructing the interaction span payload. The length of the mapping is capped at 10 (therefore no creeping memory issues), similar to howgetINP.ts
tracks candidate interactions. - INP is placed in the span
attributes
, nested inside anmeasurements
object. This is because theSpan
class doesn't have ameasurements
field. Not sure if this is the ideal approach, feedback appreciated here. - Span and envelope creation + sending happens in
_trackINP
- Should have added this to v7 (I forgot I needed this in v7), so we'll need to back port these changes.
- Looked into added an e2e playwright test, but I ended up running into v7 vs v8 issues. I think the playwright tests are currently on v7. Plan to add these tests later.
Some TODOS for future prs:
- Backport to v7
- e2e tests
- Start recording additional spans for INP once idle spans are available
- Figure out how to extend or start profiles to capture INP events
Resulting envelope should look something like this
{"sent_at":"2024-02-13T15:14:01.049Z"}
{"type":"span"}
{
"data": {
"sentry.origin": "manual",
"sentry.op": "ui.interaction.click",
"measurements": { "inp": { "value": 120, "unit": "millisecond" } },
"release": "frontend@d9135c6e4543124bb23930bb8054db3a96a6069e",
"environment": "prod"
},
"description": "/performance/browser/pageloads/",
"op": "ui.interaction.click",
"span_id": "91e77d4daa50afd8",
"start_timestamp": 1707837238.4505,
"timestamp": 1707837238.5705,
"trace_id": "bb790e8e972141d99b41a8fb7ce1db34",
"origin": "manual"
}
Some context around why the changes in this PR are needed
Decision Doc on sending INP using standalone spans https://www.notion.so/sentry/Ingesting-and-Storing-INP-8c665f20577f44268a3a06e0f4e4d1c2
Relay changes were needed to consume standalone spans including extracting INP from those spans. Here's the gh issue with problem statement: https://github.com/getsentry/relay/issues/2873 Here is the PR that was merged: https://github.com/getsentry/relay/pull/2969
For the bigger picture, we have further notes about Web Vitals + Performance Scores. I don't think this context is required, but if curious I would start here: https://www.notion.so/sentry/Browser-Starfish-Performance-Score-30bbed2e0aa540a9a755e2bc23a124fb
Closing this to break out into smaller prs and base off v7
branch:
The following 3 PRs can probably be reviewed individually: https://github.com/getsentry/sentry-javascript/pull/10702 https://github.com/getsentry/sentry-javascript/pull/10704 https://github.com/getsentry/sentry-javascript/pull/10706 They feature some smaller fixes and changes needed to do INP spans
And then this PR includes the actual updates to hook onto onINP and create the standalone INP span https://github.com/getsentry/sentry-javascript/pull/10709 It uses code changes from the 3 PRs above, so this can be reviewed later
And then this last PR is to add sample rate logic to the standalone INP span creation: https://github.com/getsentry/sentry-javascript/pull/10731 This can probably be reviewed last because it depends on all the other PRs