Problem
On the Sentry "P90 vital metrics - large accounts" dashboard, ManualOpenSearchRouter roughly doubled to ~1s p90 in production — almost entirely in SearchRouter.ListRender, which builds the initial empty-query option list. Two structural issues, both scaling linearly with account size: createFilteredOptionList is rebuilt from scratch on every open (no caching between opens; two unstable input references blocked memoization), and step 5 builds an option object for every personal detail, uncapped (19k+ on large accounts) — wasted at empty query, which never shows standalone contacts.
Solution
- Module-level cache for
createFilteredOptionList — a small keyed map (one entry per screen config, bounded to 8 with LRU eviction) validated by reference equality of its Onyx inputs (plus reference-stabilized usePrivateIsArchivedMap/visibleReportActionsData, with the active locale and a report-actions version in the key). Reopening reuses the previous result while Onyx is unchanged; each caller gets a shallow clone so in-place mutations don't leak across screens, and isSearching results aren't cached.
- New
deferContactsUntilSearch, enabled only for the SearchRouter — skips per-contact options while the query is empty; typing flips isSearching and builds the full set. Other useFilteredOptions consumers keep the default and are unaffected.
PR
#95378
Issue Owner
Current Issue Owner: @shubham1206agra
Problem
On the Sentry "P90 vital metrics - large accounts" dashboard,
ManualOpenSearchRouterroughly doubled to ~1s p90 in production — almost entirely inSearchRouter.ListRender, which builds the initial empty-query option list. Two structural issues, both scaling linearly with account size:createFilteredOptionListis rebuilt from scratch on every open (no caching between opens; two unstable input references blocked memoization), and step 5 builds an option object for every personal detail, uncapped (19k+ on large accounts) — wasted at empty query, which never shows standalone contacts.Solution
createFilteredOptionList— a small keyed map (one entry per screen config, bounded to 8 with LRU eviction) validated by reference equality of its Onyx inputs (plus reference-stabilizedusePrivateIsArchivedMap/visibleReportActionsData, with the active locale and a report-actions version in the key). Reopening reuses the previous result while Onyx is unchanged; each caller gets a shallow clone so in-place mutations don't leak across screens, andisSearchingresults aren't cached.deferContactsUntilSearch, enabled only for the SearchRouter — skips per-contact options while the query is empty; typing flipsisSearchingand builds the full set. OtheruseFilteredOptionsconsumers keep the default and are unaffected.PR
#95378
Issue Owner
Current Issue Owner: @shubham1206agra