Repository navigation
[Due for payment 2026-10-16] [$175] Perf: stop Search page header from rescanning todos on every update #103155
Description
Activity
- addedExternalAdded to denote the issue can be worked on by a contributorAdded to denote the issue can be worked on by a contributorDailyKSv2KSv2BugSomething is broken. Auto assigns a BugZero manager.Something is broken. Auto assigns a BugZero manager.
on Oct 6, 2026 Triggered auto assignment to Contributor-plus team member for initial proposal review - @getusha (
External)- changed the title
[-]Perf: stop Search page header from rescanning todos on every update[/-][+][$175] Perf: stop Search page header from rescanning todos on every update[/+]on Oct 6, 2026 Job added to Upwork: https://www.upwork.com/jobs/~022107401026948778273
Proposal
The issue's diagnosis is correct. The open PR, Perf: stop Search page header from rescanning todos on every update, is a valid fix. It changes one small behavior, described below.
What is the root cause of that problem?
SearchPageHeaderCommon.tsx:18-20callsuseSearchTypeMenuSections()only to find the current suggested search'stranslationPath. That hook callsuseHasReportAwaitingApproval. That hook subscribes to all reports, transactions, policies, and report metadata. On every render it runsgetTodoReportsForSearchKey(APPROVE), which indexes all transactions and loops over every report. Each report or transaction write re-renders the header and repeats that scan. The scan cannot change the title.What changes do you think we should make in order to solve the problem?
Read the item from
suggestedSearches[currentSearchKey], whichSearchQueryProvideralready computes from the samegetSuggestedSearches()without report or transaction subscriptions. This is what the PR does.- Same title for visible searches:
getSearchPageHeaderTitlereads onlytranslationPath. That value is constant per key, and the menu items are copies of the same objects. The types match (SearchTypeMenuItem). - Behavior change for hidden searches: The menu omits searches the user can't see, for example Approve, Pay, Export, or insights. If
currentSearchKeypoints to one of them (a deeplink, a recent search, or Approve disappearing after the last approval), the old code fell back to "Spend". The new code shows the search's own label. I think this is better: it stops the title from changing whenhasReportAwaitingApprovalflips, and it matches how the chart title already works inSearch/index.tsx:1413-1418. The reviewer should confirm it is acceptable.
Remaining cost on the same screen
This removes one of at least two scans on wide Search.
SearchTypeMenuWide.tsx:83still callsuseSearchTypeMenuSectionsForNavigation(), which runs the same hook without a focus freeze.EmptySearchViewanduseNavigationSuggestionsalso mount it. A follow-up could letgetTodoReportsForSearchKeystop at the first match, since this caller only checks.length > 0. A follow-up could also share onehasReportAwaitingApprovalvalue across all these callers.What alternative solutions did you explore? (Optional)
To keep the old "Spend" fallback for hidden searches, run
getSuggestedSearchesVisibilityon the result before using it. That adds back policy-based work for a case that is arguably wrong today, so I don't recommend it.
Next Steps for Contributor+ team:
To accept:@MelvinBot implement [this](https://github.com/Expensify/App/issues/103155)to create a draft PR.
To refine:@MelvinBot <your feedback>
To reject: Explain why you are rejecting Melvin's proposal.
- Same title for visible searches:
- addedDailyKSv2KSv2and removedWeeklyKSv2KSv2ReviewingHas a PR in reviewHas a PR in review
on Oct 6, 2026 - changed the title
[-][$175] Perf: stop Search page header from rescanning todos on every update[/-][+][Due for payment 2026-10-16] [$175] Perf: stop Search page header from rescanning todos on every update[/+]on Oct 9, 2026 The solution for this issue has been 🚀 deployed to production 🚀 in version 9.5.6-6 and is now subject to a 7-day regression period 📆. Here is the list of pull requests that resolve this issue:
If no regressions arise, payment will be issued on 2026-10-16. 🎊
The following checklist (instructions) will need to be completed before the issue can be closed. Please copy/paste the Contributor+ Checklist from here into a new comment on this GH and complete it. If you have the K2 extension, you can simply click: [this button]. If no checklist is needed for this issue, you can click: [no checklist button]
@getusha Uh oh! This issue is overdue by 2 days. Don't forget to update your issues!
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsCRITICAL
Problem
SearchPageHeaderCommoncalleduseSearchTypeMenuSections()only to look up the label of the current suggested search. That hook runsuseHasReportAwaitingApproval, which rescans all reports and rebuilds a transactions-by-report index on every report or transaction write. Opening a report from the Spend tab triggers several such writes, so the header spent about 200ms per open on a scan that cannot change its title.Solution
The header now reads
suggestedSearches[currentSearchKey]fromuseSearchQueryContext(), which is already computed there. This removes theuseSearchTypeMenuSections()call from the header.PR
#103152
Issue Owner
Current Issue Owner: @getushaUpwork Automation - Do Not Edit