Skip to content

feat(span-first): Add TTID/TTFD instrumentation#3532

Merged
buenaflor merged 20 commits intofeat/span-firstfrom
feat/span/ttid-ttfd
Feb 23, 2026
Merged

feat(span-first): Add TTID/TTFD instrumentation#3532
buenaflor merged 20 commits intofeat/span-firstfrom
feat/span/ttid-ttfd

Conversation

@buenaflor
Copy link
Copy Markdown
Contributor

@buenaflor buenaflor commented Feb 19, 2026

📜 Description

Adds streaming route TTID/TTFD span tracking (TimeToDisplayTrackerV2) and wires it through Flutter navigation/display APIs.

💡 Motivation and Context

Part of Span First of porting TTID/TTFD

💚 How did you test it?

  • fvm flutter test test/navigation/time_to_display_tracker_v2_test.dart test/navigation/sentry_navigator_observer_test.dart
  • Manual tests

📝 Checklist

  • I reviewed submitted code
  • I added tests to verify changes
  • No new PII added or SDK only sends newly added PII if sendDefaultPii is enabled
  • I updated the docs if needed
  • All tests passing
  • No breaking changes

🔮 Next steps

#skip-changelog

buenaflor and others added 3 commits February 19, 2026 21:17
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace inline TTID/TTFD streaming code in SentryNavigatorObserver
with TimeToDisplayTrackerV2.trackRoute(). Remove static ttfdSpan field
and route SentryDisplay/SentryFlutter.currentDisplay() through the
tracker on SentryFlutterOptions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…aming integration tests

Make timeToDisplayTrackerV2 a non-nullable late field on SentryFlutterOptions
instead of being created and set by SentryNavigatorObserver. Add didPop
handling for streaming mode and integration tests covering the full span v2
TTID/TTFD lifecycle through the navigator observer.

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

github-actions bot commented Feb 19, 2026

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

Generated by 🚫 dangerJS against 191cc16

@buenaflor
Copy link
Copy Markdown
Contributor Author

@sentry review

@buenaflor
Copy link
Copy Markdown
Contributor Author

@cursor review

@buenaflor
Copy link
Copy Markdown
Contributor Author

@cursor review

@buenaflor
Copy link
Copy Markdown
Contributor Author

@sentry review

@buenaflor buenaflor marked this pull request as ready for review February 20, 2026 11:34
@buenaflor buenaflor requested a review from denrase as a code owner February 20, 2026 11:34
Copilot AI review requested due to automatic review settings February 20, 2026 11:34
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds streaming-mode TTID (Time To Initial Display) and TTFD (Time To Full Display) instrumentation for Flutter navigation. It introduces TimeToDisplayTrackerV2 which uses the new span-first architecture with idle spans to track route display timing, alongside conditional routing logic to support both legacy and streaming trace lifecycles.

Changes:

  • Added TimeToDisplayTrackerV2 class for streaming-mode TTID/TTFD tracking using idle spans
  • Updated Flutter navigation observer and display APIs to conditionally use V2 tracker when in streaming mode
  • Changed default idle span timeout from 5 seconds to 3 seconds across the SDK

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/flutter/lib/src/navigation/time_to_display_tracker_v2.dart New tracker implementation using idle spans for route-level TTID/TTFD tracking
packages/flutter/lib/src/sentry_flutter_options.dart Added timeToDisplayTrackerV2 field initialization
packages/flutter/lib/src/sentry_flutter.dart Updated currentDisplay() to conditionally return V2 span IDs in streaming mode
packages/flutter/lib/src/navigation/sentry_navigator_observer.dart Added V2 tracker initialization and conditional routing in didPush/didPop
packages/flutter/lib/src/navigation/sentry_display.dart Updated reportFullyDisplayed() to conditionally call V2 tracker and improved error logging
packages/dart/lib/src/noop_hub.dart Changed startIdleSpan default idleTimeout from 5s to 3s
packages/dart/lib/src/hub_adapter.dart Changed startIdleSpan default idleTimeout from 5s to 3s
packages/flutter/example/lib/auto_close_screen.dart Moved Dio instance to class field (lifecycle change)
packages/flutter/test/navigation/time_to_display_tracker_v2_test.dart Comprehensive unit tests for TimeToDisplayTrackerV2
packages/flutter/test/navigation/sentry_navigator_observer_test.dart Added streaming mode integration tests
packages/flutter/test/navigation/sentry_display_test.dart Added tests for both streaming and non-streaming modes

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@buenaflor
Copy link
Copy Markdown
Contributor Author

@cursor review

Copy link
Copy Markdown

@cursor cursor bot left a comment

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

SentrySpanV2 startIdleSpan(
String name, {
Duration idleTimeout = const Duration(seconds: 5),
Duration idleTimeout = const Duration(seconds: 3),
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

default should be 3 seconds

buenaflor and others added 2 commits February 23, 2026 13:55
…ming tests

Guard TTFD span creation behind enableTimeToFullDisplayTracing option.
Refactor observer streaming tests to use a fake tracker, verifying
method calls instead of re-testing tracker internals.

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

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

buenaflor and others added 3 commits February 23, 2026 14:16
Implement a debug log to indicate when Time To Full Display (TTFD) tracing is disabled, returning null for currentDisplay accordingly. This enhances traceability and debugging for TTFD-related functionality.
…et test

currentDisplay() now guards on this option, so the test fixture
needs it set to true for reportFullyDisplayed to be called.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@buenaflor buenaflor merged commit 5acb39e into feat/span-first Feb 23, 2026
140 checks passed
@buenaflor buenaflor deleted the feat/span/ttid-ttfd branch February 23, 2026 15:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants