-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Description
Coming from a proposal here
Background
NavigationTabBar is a root component that stays mounted indefinitely. To function, it requires a single search query string. Currently, it retrieves this via useSearchTypeMenuSections, a heavy hook subscribing to 12 Onyx values (policies, card feeds, report counts, etc.). This hook builds a complex structure of 5 sections and 13+ items—including icons and visibility logic—even though the tab bar only needs the final query string. Many of these values, like reportCounts, change frequently, triggering full re-computations of the navigation tree regardless of which screen is active.
Problem
When NavigationTabBar subscribes to 12 frequently-changing Onyx values to build data structures required only for the Search view, if any value updates during navigation, then the entire component tree re-computes—causing ~15 re-renders and nearly 1 second of render time when moving between the inbox and reports.
Solution
- Implement useDefaultSearchQuery: A lightweight hook subscribing only to session and minimal policy data to return the fallback query string (APPROVE → SUBMIT → buildCannedSearchQuery).
- Refactor NavigationTabBar: Swap the heavy useSearchTypeMenuSections for the new hook to eliminate the overhead of menu flattening and object construction.
- Decouple Badge Logic: Move reportCounts and draftTransactions subscriptions out of the global utility and into local consumers (SearchTypeMenu.tsx) using a new formatBadgeText helper.
- Optimize Policy Loops: Consolidate double policy iterations in SearchUIUtils.ts into a single pass to determine visibility.
Performance results and screens from profiler are in the thread 😄
Draft PR: link
• Avg. renders: 14.7 → 10.6 (-28%)
• Avg. render time: 966 ms → 786 ms (-19%, −180 ms)
• Avg. span duration: 4683 ms → 4374 ms (-6.6%, −309
Metadata
Metadata
Assignees
Type
Projects
Status