fix(flutter): Add app start screen attribute#3893
Conversation
Attach the initial screen name to streaming cold and warm app start spans without propagating it to breakdown spans. Co-Authored-By: Codex <[email protected]>
Semver Impact of This PR🟢 Patch (bug fixes) 📋 Changelog PreviewThis is how your changes will appear in the changelog. Features
FixesFlutter
DependenciesDeps
Internal Changes
🤖 This preview updates automatically when you update the PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3893 +/- ##
==========================================
+ Coverage 87.35% 87.48% +0.12%
==========================================
Files 338 338
Lines 12286 12305 +19
==========================================
+ Hits 10733 10765 +32
+ Misses 1553 1540 -13
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. |
iOS Performance metrics 🚀
|
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 73dca78 | 1246.65 ms | 1265.42 ms | 18.76 ms |
| 3f47ea3 | 1263.90 ms | 1263.87 ms | -0.02 ms |
| d379a16 | 1239.65 ms | 1237.52 ms | -2.13 ms |
| 667e3c4 | 1254.70 ms | 1268.23 ms | 13.52 ms |
| 114239b | 1225.74 ms | 1230.17 ms | 4.43 ms |
| a10aff4 | 1241.67 ms | 1255.02 ms | 13.35 ms |
| 9993fa9 | 1255.60 ms | 1254.31 ms | -1.29 ms |
| dc53d48 | 1252.06 ms | 1255.61 ms | 3.55 ms |
| c1e775e | 1263.08 ms | 1275.32 ms | 12.24 ms |
| 38a22c2 | 1257.60 ms | 1259.71 ms | 2.12 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 73dca78 | 7.86 MiB | 9.44 MiB | 1.58 MiB |
| 3f47ea3 | 5.53 MiB | 5.96 MiB | 444.81 KiB |
| d379a16 | 5.83 MiB | 6.28 MiB | 459.63 KiB |
| 667e3c4 | 5.83 MiB | 6.28 MiB | 459.83 KiB |
| 114239b | 5.53 MiB | 5.96 MiB | 444.85 KiB |
| a10aff4 | 5.53 MiB | 6.00 MiB | 486.71 KiB |
| 9993fa9 | 5.83 MiB | 6.28 MiB | 459.39 KiB |
| dc53d48 | 5.65 MiB | 6.09 MiB | 446.96 KiB |
| c1e775e | 20.70 MiB | 22.46 MiB | 1.75 MiB |
| 38a22c2 | 5.73 MiB | 6.17 MiB | 453.62 KiB |
Previous results on branch: feat/span-streaming-app-vitals-start-screen
Startup times
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 441dff1 | 1245.45 ms | 1249.36 ms | 3.91 ms |
| 213ebea | 1262.19 ms | 1268.52 ms | 6.33 ms |
| ca88602 | 1243.00 ms | 1242.43 ms | -0.57 ms |
| 9bbd705 | 1254.45 ms | 1254.43 ms | -0.02 ms |
| 549f935 | 1256.57 ms | 1253.84 ms | -2.72 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 441dff1 | 5.83 MiB | 6.28 MiB | 460.59 KiB |
| 213ebea | 5.83 MiB | 6.28 MiB | 460.58 KiB |
| ca88602 | 5.83 MiB | 6.28 MiB | 460.58 KiB |
| 9bbd705 | 5.83 MiB | 6.28 MiB | 460.67 KiB |
| 549f935 | 5.83 MiB | 6.28 MiB | 460.59 KiB |
Android Performance metrics 🚀
|
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| fd88186 | 422.07 ms | 469.10 ms | 47.03 ms |
| d5a1225 | 377.37 ms | 366.56 ms | -10.81 ms |
| 1980dca | 354.77 ms | 346.96 ms | -7.82 ms |
| d0371bb | 426.85 ms | 437.14 ms | 10.29 ms |
| bfabaf2 | 408.04 ms | 444.38 ms | 36.34 ms |
| 7b21e8b | 467.74 ms | 466.24 ms | -1.50 ms |
| 2f63d89 | 415.95 ms | 424.21 ms | 8.26 ms |
| 0265ce5 | 406.39 ms | 418.48 ms | 12.09 ms |
| 7cfee3b | 498.78 ms | 516.98 ms | 18.20 ms |
| 6f47800 | 451.04 ms | 509.64 ms | 58.60 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| fd88186 | 13.93 MiB | 15.00 MiB | 1.06 MiB |
| d5a1225 | 14.31 MiB | 15.49 MiB | 1.19 MiB |
| 1980dca | 14.55 MiB | 15.87 MiB | 1.31 MiB |
| d0371bb | 14.31 MiB | 15.62 MiB | 1.31 MiB |
| bfabaf2 | 13.93 MiB | 15.06 MiB | 1.13 MiB |
| 7b21e8b | 13.93 MiB | 15.00 MiB | 1.06 MiB |
| 2f63d89 | 14.09 MiB | 15.28 MiB | 1.19 MiB |
| 0265ce5 | 14.09 MiB | 15.28 MiB | 1.19 MiB |
| 7cfee3b | 6.54 MiB | 7.70 MiB | 1.17 MiB |
| 6f47800 | 6.54 MiB | 7.69 MiB | 1.15 MiB |
Previous results on branch: feat/span-streaming-app-vitals-start-screen
Startup times
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 441dff1 | 347.68 ms | 358.04 ms | 10.36 ms |
| ca88602 | 358.16 ms | 367.40 ms | 9.24 ms |
| 213ebea | 392.60 ms | 395.90 ms | 3.30 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 441dff1 | 14.55 MiB | 15.87 MiB | 1.31 MiB |
| ca88602 | 14.55 MiB | 15.87 MiB | 1.31 MiB |
| 213ebea | 14.55 MiB | 15.87 MiB | 1.31 MiB |
There was a problem hiding this comment.
Pull request overview
This PR adds a new app-start vitals dimension (app.vitals.start.screen) to the streaming app-start parent spans (app.start.cold / app.start.warm), using the initial route/root span name, while keeping the attribute off breakdown phase spans and native child spans.
Changes:
- Add
SemanticAttributesConstants.appVitalsStartScreen. - Attach
app.vitals.start.screento the streaming app-start parent span inNativeAppStartHandlerV2. - Add Flutter integration tests covering cold/warm behavior and non-propagation to breakdown spans.
Axis Review (Standards / Spec / Correctness)
- Standards: Minor test consistency issue: new tests use raw string keys instead of
SemanticAttributesConstants.*like the rest of the file. - Spec: The implementation matches the stated behavior (attribute added to the parent app-start span only). The tests currently assert non-propagation to breakdown spans, but they do not assert non-propagation to native child spans (also called out in the PR description).
- Correctness: The production change is low-risk and correctly avoids mutating the shared
attributesmap (children keep the old map, parent gets a new one).
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| packages/flutter/lib/src/integrations/native_app_start_handler_v2.dart | Adds app.vitals.start.screen to the streaming app-start parent span attributes. |
| packages/dart/lib/src/constants.dart | Introduces a new semantic attribute constant for the screen dimension. |
| packages/flutter/test/integrations/native_app_start_handler_v2_test.dart | Adds regression tests for cold/warm spans and verifies the attribute is absent on breakdown phase spans. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Verify app.vitals.start.screen remains scoped to the parent span and is not propagated to native child spans. Co-Authored-By: Codex <[email protected]>
Match Flutter-bundled dart_style so analyze CI passes. Co-Authored-By: Cursor Grok 4.5 <[email protected]> Co-authored-by: Cursor <[email protected]>
lucas-zimerman
left a comment
There was a problem hiding this comment.
Left a non-blocking question, LGTM!
Preserve the first observed route on the prepared app-start trace so custom launch routes populate the screen dimension. Keep root and unknown routes mapped to root /. Co-Authored-By: Codex <[email protected]>
📜 Description
Add
app.vitals.start.screento streamingapp.start.coldandapp.start.warmparent spans using the initial display span name. Keep the attribute off app-start breakdown and native child spans.💡 Motivation and Context
Streaming app-start spans already report duration and start type, but omit the initial screen dimension required for mobile-vitals analysis.
💚 How did you test it?
📝 Checklist
🔮 Next steps
None.