perf(mailbox): bound paging window (maxSize) and memoize per-row timestamp #216

Merged
JMR-dev merged 1 commits from perf-mailbox-list into main 2026-07-03 15:11:52 +00:00
JMR-dev commented 2026-07-03 14:59:32 +00:00 (Migrated from github.com)

Two small, self-contained mailbox-list perf fixes from the Paging 3 audit.

1. Bound the paging window (maxSize) — Closes #212

The unified "All inboxes" PagingConfig left maxSize at the default Int.MAX_VALUE, so loaded pages were never evicted — a deep scroll accumulated every page in memory (grow-only, not a bounded sliding window). Set maxSize = MAILBOX_PAGE_SIZE * 5 (200), which satisfies the Paging invariant maxSize >= pageSize + 2*prefetchDistance (= 120). With enablePlaceholders = false, evicted leading positions drop from the loaded window and the list rendering already null-guards them.

2. remember() the per-row timestamp — Closes #213

MessageRow formatted the relative timestamp via DateUtils.getRelativeTimeSpanString un-remembered, allocating a new String (and reading System.currentTimeMillis()) on every recomposition of the row. Wrapped it in remember(message.timestampMillis) { … }.

Testing

Preflight green: assembleDebug, testDebugUnitTest, lintDebug, ktlintCheck, detekt, and compileDebugAndroidTestKotlin. No behavioural change — same UI, less resident memory on deep scroll and no per-recomposition string allocation per row.

🤖 Generated with Claude Code

Two small, self-contained mailbox-list perf fixes from the Paging 3 audit. ## 1. Bound the paging window (`maxSize`) — Closes #212 The unified "All inboxes" `PagingConfig` left `maxSize` at the default `Int.MAX_VALUE`, so loaded pages were **never evicted** — a deep scroll accumulated every page in memory (grow-only, not a bounded sliding window). Set `maxSize = MAILBOX_PAGE_SIZE * 5` (200), which satisfies the Paging invariant `maxSize >= pageSize + 2*prefetchDistance` (= 120). With `enablePlaceholders = false`, evicted leading positions drop from the loaded window and the list rendering already null-guards them. ## 2. `remember()` the per-row timestamp — Closes #213 `MessageRow` formatted the relative timestamp via `DateUtils.getRelativeTimeSpanString` **un-`remember`ed**, allocating a new `String` (and reading `System.currentTimeMillis()`) on every recomposition of the row. Wrapped it in `remember(message.timestampMillis) { … }`. ## Testing Preflight green: `assembleDebug`, `testDebugUnitTest`, `lintDebug`, `ktlintCheck`, `detekt`, and `compileDebugAndroidTestKotlin`. No behavioural change — same UI, less resident memory on deep scroll and no per-recomposition string allocation per row. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.