Skip to content

fix(mobile): cut chat re-renders, list churn, and store I/O - #122

Merged
snhsish merged 1 commit into
snhsish:mainfrom
snehasishcodes:fix/mobile-perf-batch-2
Sep 26, 2026
Merged

snhsish merged 1 commit into
snhsish:mainfrom
snehasishcodes:fix/mobile-perf-batch-2

Conversation

@snehasishcodes

Copy link
Copy Markdown

Batch #2 perf fixes from mobile deep audit.

Stores:

  • chat persist excludes draftBySession (was rewriting AsyncStorage per keystroke)
  • messages capped at 500 per session (was unbounded with base64 URLs)
  • models fetch deduped with inflight guard + 5min TTL + deeper name/provider compare

Chat screen:

  • Stable zustand selector factories via useMemo (was useCallback creating new fn per render and resubscribing)
  • connectionStatus isolated into ConnectionBanner (was re-rendering full 1000-line screen on SSE status flips)
  • modelByAgent prop memoized (was new object per render breaking ChatInput memo)
  • Pagination offset excludes local-/error- optimistic ids; initial merge sorted by created
  • Question poll backed off 5s to 30s fallback (SSE already pushes same events)
  • FlatList tuned with updateCellsBatchingPeriod/disableIntervalMomentum and onEndReached disabled while streaming

Lists:

  • sessions now prop removed; rows use 5min-bucketed useNowBucket instead of all-rows re-render per minute
  • MessageMetadata uses getState lookup (was subscribing every row to full arrays); MemoPartRenderer compares id/parts.length instead of object ref (was re-rendering all parts per token)
  • CodeBlock memoized, prism grammars deferred off render, 20k char truncate with show-more, copy timer cleanup.

- Exclude per-keystroke drafts from chat persist to stop AsyncStorage rewrite
- Cap messages store at 500 per session to bound memory
- Dedup models fetch with inflight guard, 5min TTL, deeper compare
- Stabilize zustand selectors with useMemo factories to avoid resubscribe
- Isolate connectionStatus into ConnectionBanner so SSE status stops re-rendering chat
- Memoize modelByAgent prop to keep ChatInput memo effective
- Fix pagination offset to exclude local-/error- optimistic messages
- Back off question poll 5s to 30s fallback since SSE is primary
- Tune chat FlatList and disable onEndReached while streaming
- Bucket session relative time to 5min windows and drop now prop fan-out
- Compare message parts by id/length in MemoPartRenderer, lookup models via getState
- Memoize CodeBlock, defer prism grammars, truncate 20k chars with show-more
@snhsish
snhsish merged commit dd76b28 into snhsish:main Sep 26, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants