fix: drop canceled tab navigation spans and add Inbox span context attributes#95480
Conversation
Codecov Report❌ Looks like you've decreased code coverage for some files. Please write tests to increase, or at least maintain, the existing level of code coverage. See our documentation here for how to interpret this table.
|
|
@marufsharifi Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button] |
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppNot Applicable. Android: mWeb ChromeNot Applicable. iOS: HybridAppNot Applicable. iOS: mWeb SafariNot Applicable. MacOS: Chrome / SafariScreencast.From.2026-07-08.22-00-49.mp4 |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0c4f172eaa
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
Hi @marufsharifi How's the things going? |
|
@MelvinBot review |
|
🤖 Review: LGTM — the change is correct, well-scoped, and well-tested. I verified the risky bits locally against What I checked
Minor notes (non-blocking)
I did not run the full |
|
@BartekObudzinski, I am still testing; I will update here in a few hours. thanks. |
|
thank you! |
|
@BartekObudzinski, could you please take a look at this? For the second visit, RF-1.webm
|
|
Thanks for testing this! This is expected on wide layout rather than a bug. On wide layout the Inbox sidebar is re-mounted on every tab navigation, so each visit is a full cold mount (~180ms) — there's no cached layout to re-focus, so The |
pr-95480-05.webm@BartekObudzinski, I don't see |
|
@marufsharifi Not a bug, this is my test step 5 being inaccurate, sorry my bad. The app-loading skeleton (isLoadingApp) only shows during the initial OpenApp; reloading an existing session runs reconnectApp, which never shows that skeleton, and hasEverFinishedLoading latches after the first load so it can't reappear. skeleton_shown targets the genuine cold-start: first app open that lands on another tab, then tapping Inbox while the initial load is still in flight. I'll correct step 5 to reflect that. |
|
LGTM |
|
🚧 JS00001 has triggered a test Expensify/App build. You can view the workflow run here. |
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
|
🧪🧪 Use the links below to test this adhoc build on Android, iOS, and Web. Happy testing! 🧪🧪
|
|
🚀 Deployed to staging by https://github.com/JS00001 in version: 9.4.33-0 🚀
|
|
🤖 No help site changes required. I reviewed the changes in this PR against Expensify's help site content in Why: every change here is internal Sentry/telemetry instrumentation with no user-facing impact:
The help site documents customer-facing product behavior — features, tabs, settings labels, buttons, and workflows. This PR changes none of those; it only affects how the app records internal performance telemetry, which is invisible to end users and not covered by any help article. @BartekObudzinski, no linked help site PR was created since no docs changes are required. If you believe any user-facing behavior did change here that should be documented, let me know and I'll draft the update. |

Explanation of Change
The tab-navigation spans (
ManualNavigateToInboxTab,ManualNavigateToReports*) contain events that don't measure a navigation. The big one: abandoned navigations are canceled but still sent with statusOKand wall-clock durations, so a span canceled after the laptop wakes up records the whole absence. In production that's up to 2-hour "navigations", under 1% of web events but 61% of recorded time (web avg 1250ms with them, ~420ms without). On top of that, wide vs narrow layouts (~3x cost difference) and warm re-focuses (~30ms) vs cold mounts (~150ms) were indistinguishable in the data.The fix:
canceledTabNavigationFilterdrops canceled tab-navigation spans inbeforeSend. It only matches events with a tab-navigation op AND thecanceledattribute (set exclusively bycancelSpan), so a completed navigation can never be dropped. Unit-tested.wide_layout,skeleton_shown(navigation raced app startup), andis_warm(mirrors the Reports span). Verified live on web.useSidebarOrderedReports(write-only, nothing consumed it).Note for metric consumers: the four tab-navigation metrics shift definitionally at merge (e.g. Inbox blended p90 ~-40ms, avg ~-60%), so baselines reset from the merge date. The only signal lost is the count of canceled tab navigations, dominated by benign tab-switching.
Fixed Issues
$ #95489
PROPOSAL:
Tests
[Sentry][ManualNavigateToInboxTab] Ending spanappears and its logged attributes includewide_layout(trueon wide layouts,falseon narrow) andis_warm: falseon the first visit.is_warm: true. (On wide layouts the sidebar remounts on every visit, sois_warmstaysfalse— this is expected, not a warm re-focus.)ManualNavigateToInboxTabtransaction withcanceled: trueis sent in the Sentry envelope requests (Network tab).Offline tests
N/A
QA Steps
// TODO: These must be filled out, or the issue title must include "[No QA]."
Same as tests
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectiontoggleReportand notonIconClick)Avatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))npm run compress-svg)Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari