[PERF] Isolate modals from Expensify.tsx#85449
Conversation
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b3729c107f
ℹ️ 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".
src/ExpensifyGlobalModals.tsx
Outdated
| ); | ||
| } | ||
|
|
||
| export default ExpensifyGlobalModals; |
There was a problem hiding this comment.
Memoize global modal container to prevent parent-driven rerenders
ExpensifyGlobalModals is exported as a normal function component, so it still rerenders every time Expensify rerenders (route/session/splash updates), which means the full global modal subtree is reconciled on those commits just like before. In this performance refactor, that prevents the intended isolation of modal work and leaves the optimization largely ineffective unless the component is wrapped with React.memo (or equivalent bailout).
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Wrong, Codex please acknowledge the React Compiler exists
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 04aadfa2db
ℹ️ 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".
| <KeyboardShortcutsHandler /> | ||
| <ThreeDSAuthHandler /> | ||
| <UserStatusHandler /> | ||
| <AuthenticatedGlobalModals /> |
There was a problem hiding this comment.
Gate authenticated modal managers on app init completion
Mounting AuthenticatedGlobalModals here removes the old shouldInit guard from Expensify (isNavigationReady && hasAttemptedToOpenPublicRoom && !!preferredLocale). NavigationRoot renders <AppNavigator /> before its onReady callback flips isNavigationReady, so persisted startup state like ONYXKEYS.SCREEN_SHARE_REQUEST or ONYXKEYS.NVP_APP_REVIEW can now open ConfirmModals during the splash/OldDot handoff instead of after bootstrapping finishes. That changes cold-start behavior for authenticated users in a way the previous code explicitly avoided.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
This is a valid concern. In order to keep AuthenticatedGlobalModals in AuthScreens we'd need to either prop drill it or make it available from context. IMO not worth the trouble.
Reverting to the OG idea of just decomposing them
|
@ShridharGoel 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] |
src/Expensify.tsx
Outdated
| </> | ||
| )} | ||
|
|
||
| {shouldInit && <GlobalModals updateAvailable={updateAvailable} />} |
There was a problem hiding this comment.
updateAvailable does not seem like a valid concern of GlobalModals. Can we subscribe inside instead?
There was a problem hiding this comment.
I see only the UpdateAppModal can fetch this and render accordingly
There was a problem hiding this comment.
yeah, left it here to keep logging on src/Expensify.tsx#213 intact and not duplicte subscriptions, but sure can move it down.
src/GlobalModals.tsx
Outdated
| function GlobalModals({updateAvailable}: GlobalModalsProps) { | ||
| return ( | ||
| <> | ||
| {!!updateAvailable && <UpdateAppModal />} |
There was a problem hiding this comment.
yeah we can for sure subscribe to this internally instead
|
No product review needed |
Reviewer Checklist
Screenshots/Videos |
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.
|
|
🚧 @mountiny 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/mountiny in version: 9.3.42-0 🚀
Bundle Size Analysis (Sentry): |







Explanation of Change
This PR move the six global modals out of Expensify and into a dedicated React.memo-wrapped child component. This eliminates ~3–8ms of wasted reconciliation per commit without changing any modal behavior or visual output.
Fixed Issues
$ #85634
PROPOSAL: on slack
Tests
Some of the modal scenarios check:
Emoji modal
App review modal
Onyx.set('nvp_appReview', {trigger: 'smartscan'});Update modal
Onyx.set('updateRequired', true);Offline tests
Same as tests
QA Steps
Same as tests
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectiontoggleReportand notonIconClick)src/languages/*files and using the translation methodSTYLE.md) were followedAvatar, 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.ScrollViewcomponent to make it scrollable when more elements are added to the page.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
MacOS: Chrome / Safari
Screen.Recording.2026-03-19.at.17.26.03.mov
Perf related screenshots
Web
IOS