Skip to content

Dynamic Option Loading to Eliminate Background Lag in OptionListContextProvider #75731

@mountiny

Description

@mountiny

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.

  1. Per-Screen Loading: Replace the global context with local, screen-specific option providers that only compute data when the screen is active.
  2. 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.
  3. 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 ⚠️ 40% slower initially, then similar
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 OwnerCurrent Issue Owner: @rojiphil
Issue OwnerCurrent Issue Owner: @martasudol

Metadata

Metadata

Labels

BugSomething is broken. Auto assigns a BugZero manager.ExternalAdded to denote the issue can be worked on by a contributorReviewingHas a PR in reviewWeeklyKSv2

Type

No type

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions