Skip to content

feat(tracing): Add reportFullyDisplayed() static API#6419

Open
antonis wants to merge 6 commits into
mainfrom
antonis/feat/report-fully-displayed
Open

feat(tracing): Add reportFullyDisplayed() static API#6419
antonis wants to merge 6 commits into
mainfrom
antonis/feat/report-fully-displayed

Conversation

@antonis

@antonis antonis commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

📢 Type of change

  • Bugfix
  • New feature
  • Enhancement
  • Refactoring

📜 Description

Adds Sentry.reportFullyDisplayed() as a public imperative API for signaling Time to Full Display (TTFD). This is the imperative equivalent of the <TimeToFullDisplay> component, matching the cross-SDK Sentry.reportFullyDisplayed() API specified at develop.sentry.dev.

💡 Motivation and Context

Closes #6341

💚 How did you test it?

Unit tests — 6 new tests covering:

  • Happy path: TTFD span created with correct op, status, and measurement via integration
  • TTFD-before-TTID: timestamp adjusted to TTID end
  • No active span: no-op with warning, no crash
  • No TTID: no TTFD span created
  • Nested child span: correctly resolves root span ID
  • Idempotency: second call produces no duplicate spans

All 45 time-to-display tests pass. Lint, build, and circular dep check clean.

E2E verification — Tested with the sample app's SpaceflightNewsScreen calling Sentry.reportFullyDisplayed() after articles load. Verified in Sentry that:

  • ui.load.full_display span appears with status ok (~2.1s duration)
  • time_to_full_display measurement is set
  • TTFD > TTID (as expected — TTFD fires after API response, TTID on first render)
  • Multiple navigations produce consistent results with no duplicates

Example trace

📝 Checklist

🔮 Next steps

Add imperative `Sentry.reportFullyDisplayed()` API for signaling Time to
Full Display, matching the cross-SDK spec at develop.sentry.dev. This is
the imperative equivalent of the `<TimeToFullDisplay>` component.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Semver Impact of This PR

None (no version bump detected)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


  • feat(tracing): Add reportFullyDisplayed() static API by antonis in #6419
  • chore(deps): update JavaScript SDK to v10.64.0 by github-actions in #6418
  • test(android): Guard reactNativeArchitectures fix with a subset-ABI build by antonis in #6416
  • fix(deps): Bump js-yaml to 3.15.0 by antonis in #6414
  • feat(ios): Consume sentry-cocoa as a prebuilt xcframework by default by alwx in #6413
  • feat(tracing): Add extend app start API for standalone app start by antonis in #6392
  • fix(ios): Skip source maps upload on Debug builds by antonis in #6405
  • fix(ci): Bump codeql-action/init to v4.36.3 to match analyze/autobuild by antonis in #6410
  • Revert "feat(ios): Default to consuming sentry-cocoa as an xcframework" (feat(ios): Default to consuming sentry-cocoa as an xcframework #6381) by alwx in #6412

🤖 This preview updates automatically when you update the PR.

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor
Messages
📖 Do not forget to update Sentry-docs with your feature once the pull request gets approved.

Generated by 🚫 dangerJS against 2461e43

@antonis antonis added the ready-to-merge Triggers the full CI test suite label Jul 8, 2026
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Comment thread packages/core/src/js/tracing/timetodisplay.tsx Outdated
Store the timestamp in a JS-side map and let the timeToDisplayIntegration
pick it up during processEvent, instead of calling updateFullDisplaySpan
directly. The previous approach failed in production because it relied on
updateInitialDisplaySpan to drain the deferred queue, but that function
is never called in the real component/navigation flow — TTID timestamps
are read from native during processEvent.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@sentry

sentry Bot commented Jul 8, 2026

Copy link
Copy Markdown

📲 Install Builds

Android

🔗 App Name App ID Version Configuration
Sentry RN io.sentry.reactnative.sample 8.17.2 (97) Release

⚙️ sentry-react-native Build Distribution Settings

Comment thread packages/core/test/tracing/timetodisplay.test.tsx
Comment thread packages/core/src/js/tracing/integrations/timeToDisplayIntegration.ts Outdated
Comment thread packages/core/test/tracing/timetodisplay.test.tsx
…e spans

- Use `getRootSpan` in `reportFullyDisplayed()` so the stored key matches the
  integration's `rootSpanId` lookup, even when called inside a nested child span.
- Add early return in `addTimeToFullDisplay` when an existing ok TTFD span is
  found, preventing duplicate `ui.load.full_display` spans.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 3df6c17. Configure here.

Comment thread packages/core/src/js/tracing/integrations/timeToDisplayIntegration.ts Outdated
Pop both native and imperative timestamps unconditionally so the
imperative entry is cleaned up even when native takes priority.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

iOS (legacy) Performance metrics 🚀

  Plain With Sentry Diff
Startup time 3849.60 ms 1230.16 ms -2619.45 ms
Size 4.98 MiB 6.53 MiB 1.55 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
5257d80+dirty 3854.39 ms 1234.28 ms -2620.11 ms
bfba737+dirty 3857.19 ms 1228.77 ms -2628.42 ms
ce7b368+dirty 3811.84 ms 1217.69 ms -2594.15 ms
ab203f9+dirty 3848.07 ms 1219.71 ms -2628.35 ms
5a010b7+dirty 3838.85 ms 1214.98 ms -2623.87 ms
6177334+dirty 3834.85 ms 1217.58 ms -2617.28 ms
9474ead+dirty 3864.29 ms 1223.55 ms -2640.74 ms
6176a94+dirty 3836.50 ms 1217.64 ms -2618.86 ms
ae37560+dirty 3832.10 ms 1219.09 ms -2613.02 ms
f170ec3+dirty 3822.26 ms 1218.33 ms -2603.93 ms

App size

Revision Plain With Sentry Diff
5257d80+dirty 5.15 MiB 6.69 MiB 1.54 MiB
bfba737+dirty 4.98 MiB 6.51 MiB 1.53 MiB
ce7b368+dirty 4.98 MiB 6.51 MiB 1.53 MiB
ab203f9+dirty 4.98 MiB 6.51 MiB 1.53 MiB
5a010b7+dirty 5.15 MiB 6.69 MiB 1.54 MiB
6177334+dirty 5.15 MiB 6.68 MiB 1.53 MiB
9474ead+dirty 5.15 MiB 6.71 MiB 1.55 MiB
6176a94+dirty 5.15 MiB 6.68 MiB 1.53 MiB
ae37560+dirty 5.15 MiB 6.70 MiB 1.54 MiB
f170ec3+dirty 5.15 MiB 6.69 MiB 1.53 MiB

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Android (legacy) Performance metrics 🚀

  Plain With Sentry Diff
Startup time 420.49 ms 452.66 ms 32.17 ms
Size 49.74 MiB 55.26 MiB 5.52 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
ef27341+dirty 412.94 ms 443.98 ms 31.04 ms
a0d8cf8+dirty 411.71 ms 467.57 ms 55.87 ms
1e5d96d+dirty 519.43 ms 543.62 ms 24.19 ms
4acd4e9+dirty 414.45 ms 448.55 ms 34.10 ms
d7d54c6+dirty 458.06 ms 479.94 ms 21.87 ms
04207c4+dirty 459.19 ms 518.54 ms 59.35 ms
7ac3378+dirty 404.78 ms 439.84 ms 35.06 ms
bc0d8cf+dirty 412.37 ms 466.26 ms 53.89 ms
0b5120f+dirty 503.22 ms 538.60 ms 35.38 ms
5ee78d6+dirty 551.80 ms 568.27 ms 16.47 ms

App size

Revision Plain With Sentry Diff
ef27341+dirty 48.30 MiB 53.54 MiB 5.24 MiB
a0d8cf8+dirty 48.30 MiB 53.49 MiB 5.19 MiB
1e5d96d+dirty 49.74 MiB 54.81 MiB 5.07 MiB
4acd4e9+dirty 49.74 MiB 55.26 MiB 5.52 MiB
d7d54c6+dirty 49.74 MiB 55.09 MiB 5.34 MiB
04207c4+dirty 43.75 MiB 48.12 MiB 4.37 MiB
7ac3378+dirty 43.75 MiB 48.13 MiB 4.37 MiB
bc0d8cf+dirty 48.30 MiB 53.48 MiB 5.18 MiB
0b5120f+dirty 48.30 MiB 53.58 MiB 5.28 MiB
5ee78d6+dirty 48.30 MiB 53.58 MiB 5.28 MiB

- Use `timestampInSeconds()` instead of `Date.now() / 1000` for clock
  consistency with the rest of the tracing module.
- Cap `_imperativeTtfdTimestamps` at 50 entries, evicting the oldest
  when full, to prevent unbounded growth on sampled-out transactions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 2461e43. Configure here.

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Android (new) Performance metrics 🚀

  Plain With Sentry Diff
Startup time 419.22 ms 464.78 ms 45.56 ms
Size 49.74 MiB 55.26 MiB 5.52 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
20fbd51+dirty 594.38 ms 655.35 ms 60.97 ms
21a1e70+dirty 437.55 ms 507.10 ms 69.56 ms
4acd4e9+dirty 431.33 ms 477.68 ms 46.35 ms
9474ead+dirty 432.18 ms 481.92 ms 49.73 ms
d7d54c6+dirty 423.54 ms 498.56 ms 75.02 ms
64630e5+dirty 427.13 ms 486.67 ms 59.55 ms
3d377b5+dirty 425.38 ms 440.67 ms 15.30 ms
94af3bd+dirty 413.04 ms 451.76 ms 38.71 ms
7a89652+dirty 405.00 ms 437.04 ms 32.04 ms
2c735cc+dirty 435.20 ms 459.48 ms 24.28 ms

App size

Revision Plain With Sentry Diff
20fbd51+dirty 49.74 MiB 54.81 MiB 5.07 MiB
21a1e70+dirty 49.74 MiB 54.82 MiB 5.07 MiB
4acd4e9+dirty 49.74 MiB 55.26 MiB 5.52 MiB
9474ead+dirty 48.30 MiB 53.61 MiB 5.30 MiB
d7d54c6+dirty 49.74 MiB 55.09 MiB 5.34 MiB
64630e5+dirty 49.74 MiB 54.82 MiB 5.07 MiB
3d377b5+dirty 43.94 MiB 49.00 MiB 5.06 MiB
94af3bd+dirty 48.30 MiB 53.57 MiB 5.26 MiB
7a89652+dirty 48.30 MiB 53.60 MiB 5.30 MiB
2c735cc+dirty 43.94 MiB 48.94 MiB 5.00 MiB

@antonis antonis marked this pull request as ready for review July 8, 2026 12:08
@antonis antonis requested review from a team, alwx and lucas-zimerman as code owners July 8, 2026 12:08
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

iOS (new) Performance metrics 🚀

  Plain With Sentry Diff
Startup time 3866.45 ms 1244.86 ms -2621.60 ms
Size 4.98 MiB 6.53 MiB 1.55 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
bfba737+dirty 3834.18 ms 1222.80 ms -2611.38 ms
ce7b368+dirty 3851.41 ms 1222.37 ms -2629.04 ms
ab203f9+dirty 3850.11 ms 1213.16 ms -2636.95 ms
6176a94+dirty 3854.15 ms 1221.77 ms -2632.38 ms
100ce80+dirty 3843.57 ms 1226.46 ms -2617.12 ms
1e5d96d+dirty 3845.93 ms 1222.51 ms -2623.42 ms
a3265b6+dirty 3844.26 ms 1235.60 ms -2608.66 ms
d2eadf8+dirty 3841.53 ms 1216.15 ms -2625.39 ms
40c9884+dirty 3826.11 ms 1217.04 ms -2609.07 ms
64630e5+dirty 3845.49 ms 1215.19 ms -2630.30 ms

App size

Revision Plain With Sentry Diff
bfba737+dirty 4.98 MiB 6.51 MiB 1.53 MiB
ce7b368+dirty 4.98 MiB 6.51 MiB 1.53 MiB
ab203f9+dirty 4.98 MiB 6.50 MiB 1.52 MiB
6176a94+dirty 5.15 MiB 6.68 MiB 1.53 MiB
100ce80+dirty 5.15 MiB 6.67 MiB 1.51 MiB
1e5d96d+dirty 4.98 MiB 6.46 MiB 1.49 MiB
a3265b6+dirty 5.15 MiB 6.68 MiB 1.53 MiB
d2eadf8+dirty 5.15 MiB 6.67 MiB 1.51 MiB
40c9884+dirty 4.98 MiB 6.51 MiB 1.53 MiB
64630e5+dirty 4.98 MiB 6.46 MiB 1.49 MiB

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-merge Triggers the full CI test suite

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Evaluate Sentry.reportFullyDisplayed() static API for cross-SDK alignment

1 participant