Repository navigation
feat(core): Add __SENTRY_EXCLUDE_TRANSACTIONS__ flag to tree-shake transaction code - #26144
sentry-junior[bot] wants to merge 3 commits into
Conversation
…transaction code With span streaming, the code that builds and processes transaction events is dead but still ships. Replacing `__SENTRY_EXCLUDE_TRANSACTIONS__` with `true` makes the SDK always stream spans and lets bundlers drop those paths. Defaults are unchanged. Refs #22580 Co-Authored-By: BYK <126780+BYK@users.noreply.github.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 3 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit e6aa1e9. Configure here.
|
|
||
| expect(client.getOptions().integrations.map(integration => integration.name)).toContain('SpanStreaming'); | ||
| }); | ||
| }); |
There was a problem hiding this comment.
Feature PR lacks integration tests
Low Severity
This feature PR only adds unit tests. Flagged because the review guidelines require at least one integration or E2E test for feat PRs. The new file covers flag semantics in isolation, but not a built-package path that proves a startSpan segment still becomes a span envelope item when the flag is true, including with traceLifecycle: 'static'.
Triggered by project rule: PR Review Guidelines for Cursor Bot
Reviewed by Cursor Bugbot for commit e6aa1e9. Configure here.
size-limit report 📦Compared: 4846463 (PR test merge using develop at 8c2bc97) Against: 8c2bc97 (develop) · base run #65215 ✅ Baseline matches: this diff contains only this PR's changes.
|
…ns are excluded With `__SENTRY_EXCLUDE_TRANSACTIONS__`, `traceLifecycle: 'static'` is ignored, so the Cloudflare client must still add its own `spanStreamingIntegration` with `flushOnSegmentEnd: false` instead of inheriting the default one from `ServerRuntimeClient`. Also use the conventions constants in the web vitals test.
Optional E2E testsSome optional checks were not successful. They do not block the merge. 6 not successful, 50 successful. See the run.
Successful checks
|
|
Why does this PR result in larger bundle sizes when this flag isn't set? 🤔 This is expected for the npm output. The flags remain so users can choose what they want to filter, but this shouldn't be impacting our CDN bundles. |
|
The extra bytes come from the guards themselves. The browser path has 7 inline guards: 3 in I replaced all 7 guards with
So the guards account for basically the whole CI delta, and the raw numbers line up with the +612 B on the uncompressed CDN tracing bundles. Cheaper guard forms I tried:
How much of the flag's saving each site carries (esbuild raw, flag set):
Ways to cut the default cost:
I'm happy to do either one, or both. Just say which you'd prefer. |
This is the correct route! |
…lse` in CDN bundles CDN bundles always keep transaction support, so the unresolved runtime checks for the flag only added bytes there.


Why: Span streaming is the default in v11, but a streaming app still ships the code that builds and processes transaction events (
_convertSpanToTransaction, the transaction branch ofprocessBeforeSend, gen_ai extraction, transaction-event conversion helpers, the web vitals measurements branch). RuntimehasSpanStreamingEnabled(client)/traceLifecyclechecks keep it alive.__SENTRY_TRACING__: false(#22835) only helps apps that don't trace at all.This adds an opt-in build flag. Replacing
__SENTRY_EXCLUDE_TRANSACTIONS__withtruemeans the SDK always streams spans:traceLifecycle: 'static'is ignored (normalized to'stream', and server clients still addspanStreamingIntegration), and the transaction code paths become dead code. Segments are still sent as span envelopes. When the flag isn't defined, behavior is unchanged.The guard sits inline at each call site, like
__SENTRY_TRACING__. A shared module-level constant doesn't work: esbuild inlines it across modules too late to remove the dead branches, and doesn't inline it within a module that has imports.Size (esbuild 0.27, minify, ESM, browser,
__SENTRY_DEBUG__: false;BrowserClient+browserTracingIntegration,tracesSampleRate: 1,setCurrentClient,client.init()):developtrueWith webpack via size-limit (
init+browserTracingIntegration), the flag saves 1,405 B gzip (49,304 → 47,899). The new size-limit entry tracks it.I ran an end-to-end check against the built packages: with the flag, a
startSpansegment produces aspanenvelope item, including whentraceLifecycle: 'static'is passed. Without the flag, behavior is unchanged (spanfor stream,transactionfor static).Left in:
_processEvent(dropped-span outcomes,transaction_infosource), which is small and still handles manually capturedtype: 'transaction'eventsmaybeWarnAboutIgnoredTransactionOptionsmeasurementsingetSpanJSON/static span JSONhasSpanStreamingEnabled(client) ? … : …ternaries in integrations (span names, attribute keys), plus static branches inbrowser-utilsweb-vitals/spans.tsandinteractions.tstraceLifecycle !== 'static'checkbundleSizeOptimizations.excludeTransactionsoption in the bundler plugins (left for a follow-up, once the flag name is settled)How to review: Start with
sentrySpan.tsandclient.ts.excludeTransactions.test.tscovers the flag semantics.Unsure about:
__SENTRY_EXCLUDE_*__convention, and Investigate tree shaking of transaction code when span streaming is used #22580 doesn't propose a name.Refs #22580
via @BYK.
--
View Session in Sentry