Hacktoberfest 2026:維護者為十月標記出來的 issue,仍然開放、適合新手。 瀏覽 Hacktoberfest issue

Unsampled pageload span is profiled when profileLifecycle is 'trace' (browser UI profiling)

未關閉 適合新手
#25,497 1 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

維護者通常 1 天內回覆

@Jxxunnn 已經在處理了。

開始於 2026年10月19日。

  • #25498 來自 @Jxxunnn —— 未關閉

評估

難度
2/5
預估耗時
1-3 小時
新手友好度
82/100
Issue 類型
缺陷
描述清晰度
描述清楚
活躍度
活躍
技術堆疊
javascript, typescript

研究方向

從 packages/browser/src/profiling/UIProfiler.ts 開始,比較 notifyRootSpanActive() 與 _setupTraceLifecycleListeners() 中的 spanStart 監聽器。檢查現有的 profiling 測試是否涵蓋設定時已處於作用中且未取樣的根 span。完成標準是:此情況不會啟動 profiler,也不會傳送 profile 資料區塊;而已取樣的根 span 仍會啟動 profiling。

由索引模型根據 Issue 內容生成。

描述

Browser Waiting for: Product Owner
Is there an existing issue for this?
How do you use Sentry?

Sentry Saas (sentry.io)

Which SDK are you using?

@sentry/browser

SDK Version

@sentry/browser 11.8.0 (also reproduced on 11.4.0; UIProfiler.ts on develop is unchanged as of 2026-10-19)

Framework Version

No response

Link to Sentry event

No response

Reproduction Example/SDK Setup
import * as Sentry from '@sentry/browser';

Sentry.init({
  dsn: '<dsn>',
  integrations: [Sentry.browserTracingIntegration(), Sentry.browserProfilingIntegration()],
  tracesSampleRate: 0, // pageload span NOT sampled -> expect NO profiling
  profileSessionSampleRate: 1,
  profileLifecycle: 'trace',
});

The page is served with Document-Policy: js-profiling.

Steps to Reproduce
  1. Initialize the SDK with profileLifecycle: 'trace', profileSessionSampleRate: 1 and tracesSampleRate: 0 (see SDK setup above).
  2. Load the page. The pageload span is not sampled (isRecording() === false, traceFlags === 0).
  3. Observe that new Profiler(...) is called once and a profile_chunk envelope is sent when the pageload span ends.
Expected Result

The pageload span is not sampled, so trace lifecycle profiling should not start. This is how root spans started after setup are already handled.

Actual Result

The profiler starts for the unsampled pageload span and a profile_chunk is sent.

I checked this in Chromium with a window.Profiler stub that counts constructor calls and an in-memory transport:

  • tracesSampleRate: 0, profileSessionSampleRate: 1: profiler started once, profile_chunk sent
  • tracesSampleRate: 0, profileSessionSampleRate: 0: profiler not started (control)
  • tracesSampleRate: 1, profileSessionSampleRate: 1: profiler started once, profile_chunk and the pageload span sent (expected)
  • tracesSampleRate: 0, profileSessionSampleRate: 1, pageload instrumentation off, an unsampled root span started after init: profiler not started

The last case shows that only the root span that is already active at setup skips the sampling check.

Additional Context
Root cause (source walkthrough)

In packages/browser/src/profiling/integration.ts (develop):

  • After profiler.initialize(client), setup calls profiler.notifyRootSpanActive(rootSpan) for the active root span. The comment says "If there is an active, sampled root span already, notify the profiler".
  • Setup calls it again in a setTimeout(0). This is the path that picks up the pageload span that browserTracingIntegration starts in afterAllSetup.

In packages/browser/src/profiling/UIProfiler.ts:

  • The spanStart listener registered by _setupTraceLifecycleListeners() returns early when !span.isRecording() ("Only count sampled root spans").
  • notifyRootSpanActive() only checks the lifecycle mode and _sessionSampled. It then registers the span and calls _beginProfiling() without checking rootSpan.isRecording().

So an unsampled root span that is already active at setup starts the profiler. The unsampled span still emits spanEnd, so the profile runs for the length of the pageload.

#17619, which added the trace lifecycle, describes it as "Starts when the first sampled root span starts".

Impact

With profileSessionSampleRate: 1, unsampled pageload spans can still start UI profiling in supported browsers. Reducing tracesSampleRate, even to 0, does not prevent this startup path. This can add unintended profiling overhead and profile usage, without a sampled pageload span to correlate with the resulting chunks.

Related

#22927 was the same kind of gap in the Node trace lifecycle, there for the session sampling decision.

Suggested fix

Return early in notifyRootSpanActive() when !rootSpan.isRecording(), matching the spanStart listener. Happy to open a PR.

主要語言
TypeScript
星號
8.8k
分支
1.9k
平均合併
1 天 12 小時
30 天內合併 PR
598

環境準備

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

getsentry/sentry-javascript 的其他 Issue

查看 getsentry/sentry-javascript 的全部 Issue

相似的 Issue

更多 TypeScript Issue

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。