When investigating slow app starts or TTFD, users currently need to dig into individual HTTP request spans to determine if network activity was the cause. Adding aggregate network measurements to the parent span would answer "was this slow startup caused by network?" at a glance.
Proposed measurements on app start and TTFD spans:
- Request count
- Failed request count
- Total duration
- Slowest request duration + host
Implementation approach
Add aggregation logic in a processEvent hook, running after both appStartIntegration and timeToDisplayIntegration have processed the event:
- Iterate
event.spans for op === 'http.client' spans.
- Filter to those whose time range overlaps with the app start or TTFD span.
- Compute summary measurements and add to
event.measurements.
getSpanDescendants() is already used extensively in the codebase (e.g. onSpanEndUtils.ts filters for http.client children).
Complexity considerations
- Integration ordering: Aggregation must run after app start and TTD integrations. Integration execution order depends on the
integrations array order.
- Standalone app start mode: HTTP spans may live on a different transaction than the standalone app start data. Needs a design decision on how to handle this.
- Time window matching: Spans that start before TTFD but end after need a policy decision (include, exclude, partial).
- Response body size:
content-length is not currently on HTTP tracing spans (only in replay breadcrumb path in xhrUtils.ts). Adding it would require upstream @sentry/browser changes — consider deferring bytes metrics to a follow-up.
Scope
JS only. All HTTP spans are created in the JS layer. The aggregation runs in processEvent.
When investigating slow app starts or TTFD, users currently need to dig into individual HTTP request spans to determine if network activity was the cause. Adding aggregate network measurements to the parent span would answer "was this slow startup caused by network?" at a glance.
Proposed measurements on app start and TTFD spans:
Implementation approach
Add aggregation logic in a
processEventhook, running after bothappStartIntegrationandtimeToDisplayIntegrationhave processed the event:event.spansforop === 'http.client'spans.event.measurements.getSpanDescendants()is already used extensively in the codebase (e.g.onSpanEndUtils.tsfilters forhttp.clientchildren).Complexity considerations
integrationsarray order.content-lengthis not currently on HTTP tracing spans (only in replay breadcrumb path inxhrUtils.ts). Adding it would require upstream@sentry/browserchanges — consider deferring bytes metrics to a follow-up.Scope
JS only. All HTTP spans are created in the JS layer. The aggregation runs in
processEvent.