-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Description
Coming from proposal here
Background:
Our app currently uses a global OptionListContextProvider that manages and processes option data across multiple screens. Once initialized, it remains active for the entire app lifecycle. Any event that updates user data or syncs reports can trigger the context to update, even when the related screens are not visible. This design was intended to improve responsiveness by pre-caching options globally.
Problem:
When updates occur anywhere in the app, they trigger full option recalculations across all screens, causing unpredictable CPU spikes that interrupt navigation and degrade user responsiveness.
Solution:
We will optimize OptionListContextProvider by decoupling global option processing into on-demand, per-screen loading.
- Per-Screen Loading: Replace the global context with local, screen-specific option providers that only compute data when the screen is active.
- Filter Before Process: Introduce createFilteredOptionList() to filter, sort, and limit reports before heavy processing. For instance filter relevant reports → Sort by lastVisibleActionCreated → Slice top 500 → Process options. This reduces expensive processReport() calls by ~97.5%, cutting option list generation time from ~144 ms to ~45 ms.
- Dynamic Pagination: Load further data in batches of 500 as users scroll, avoiding upfront computation costs.Table 1: Jason's Account (4,002 reports)
| Metric | Main | Feat (Init) | Feat (Scroll) | Improvement |
|---|---|---|---|---|
| Total reports | 4,002 | 4,002 | 4,002 | — |
| After filter | — | 4,002 | 4,002 | — |
| Reports processed | 3,536 | 500 | 600–800 | ✅ 85.9% fewer initially |
| Option list generation time (ms) | 150.30 | 37.90 | 38.40–52.00 | ✅ 74.8% faster |
| Generated options | 3,907 | 871 | 971–1,171 | ✅ 77.7% fewer initially |
| Table 2: Applause admin heavy account (582 reports) | ||||
| Metric | Main | Feat (Init) | Feat (Scroll) | Improvement |
| ---------------------------------- | ------ | ------------- | ---------------- | ----------------------------------------- |
| Total reports | 582 | 582 | 582 | — |
| After filter | — | 582 | 582 | — |
| Reports processed | 582 | 500 | 582 | ✅ 14% fewer initially |
| Option list generation time (ms) | 114.80 | 160.90 | 110.50–117.90 | |
| Generated options | 23,046 | 22,964 | 23,046 | — |
Results:
No background recomputation during navigation.
CPU usage stable with no random spikes.
Navigation performance smooth and predictable.
Impact:
This redesign eliminates nondeterministic background lag, ensuring consistent performance and a smoother user experience. The same pattern can later be extended to other list-based views such as WorkspaceInvitePage.
Draft PR: Expensify/App#74071
Issue Owner
Current Issue Owner: @rojiphilIssue Owner
Current Issue Owner: @martasudolMetadata
Metadata
Labels
Type
Projects
Status