perf(mailbox): bound the unified-inbox paging window with PagingConfig.maxSize #212

Closed
opened 2026-07-03 14:51:38 +00:00 by JMR-dev · 0 comments
JMR-dev commented 2026-07-03 14:51:38 +00:00 (Migrated from github.com)

Source: perf audit of the Paging 3 usage (finding #1).

The unified "All inboxes" list is paged (Room PagingSource → Pager, issue #124), but its PagingConfig leaves maxSize at the default Int.MAX_VALUE, so loaded pages are never evicted — deep scrolling accumulates every page in memory. It's a grow-only window, not the bounded sliding window the pattern intends.

Location: the only PagingConfig in the app — MailRepositoryImpl.pagedUnifiedFolderMessages (app/src/main/kotlin/org/libremail/data/repository/MailRepositoryImpl.kt:92): pageSize=40, initialLoadSize=120, enablePlaceholders=false, maxSize unset, prefetchDistance default (=40).

Fix: set maxSize to a finite value (e.g. 200, ~5 pages) so eviction bounds resident rows regardless of scroll depth. Must satisfy maxSize >= pageSize + 2*prefetchDistance (= 40 + 80 = 120). Safe with enablePlaceholders=false: the list rendering already null-guards evicted positions and "select all" reads only the loaded snapshot.

**Source:** perf audit of the Paging 3 usage (finding #1). The unified "All inboxes" list is paged (Room `PagingSource` → `Pager`, issue #124), but its `PagingConfig` leaves **`maxSize` at the default `Int.MAX_VALUE`**, so loaded pages are **never evicted** — deep scrolling accumulates every page in memory. It's a grow-only window, not the bounded sliding window the pattern intends. **Location:** the only `PagingConfig` in the app — `MailRepositoryImpl.pagedUnifiedFolderMessages` (`app/src/main/kotlin/org/libremail/data/repository/MailRepositoryImpl.kt:92`): `pageSize=40`, `initialLoadSize=120`, `enablePlaceholders=false`, **`maxSize` unset**, `prefetchDistance` default (=40). **Fix:** set `maxSize` to a finite value (e.g. `200`, ~5 pages) so eviction bounds resident rows regardless of scroll depth. Must satisfy `maxSize >= pageSize + 2*prefetchDistance` (= 40 + 80 = 120). Safe with `enablePlaceholders=false`: the list rendering already null-guards evicted positions and "select all" reads only the loaded snapshot.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: JMR-dev/LibreMail#212