perf(mailbox): page the per-account folder view and search (currently whole folder/inbox in memory) #214

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

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

Issue #124 paged the unified "All inboxes" browse list, but the per-account folder view and all search paths are still not paged — they load the whole folder / entire unified inbox into memory:

  • Per-account folder browse: MailboxViewModel.messages (app/src/main/kotlin/org/libremail/ui/mailbox/MailboxViewModel.kt:128) via observeFolderMessages → rendered as items(messages, key = { it.id }) (MailboxScreen.kt:348). Loads the entire folder as List<Message>.
  • Unified search: observeUnifiedFolderSummaries (app/src/main/kotlin/org/libremail/data/local/dao/MessageDao.kt:52) — its own KDoc notes it "materializes the entire unified inbox (~thousands of rows) on every emission."
  • Per-account search: same whole-folder path.

This re-introduces the whole-list-in-memory cost that #124 removed, the moment the user switches to a single account or runs a search.

Fix: add a Room PagingSource variant for the per-account folder (mirroring pagingUnifiedFolderSummaries in MessageDao), plus a paged/limited search, and wire them through MailboxViewModel + MailboxScreen the same way the unified browse list is paged. Reuse the shared PagingConfig (see #1). Keep the lazy keys and the load-state handling consistent with the unified list.

**Source:** perf audit of the Paging 3 usage (finding #3). Issue #124 paged the unified "All inboxes" browse list, but the **per-account folder view and all search paths are still not paged** — they load the whole folder / entire unified inbox into memory: - **Per-account folder browse:** `MailboxViewModel.messages` (`app/src/main/kotlin/org/libremail/ui/mailbox/MailboxViewModel.kt:128`) via `observeFolderMessages` → rendered as `items(messages, key = { it.id })` (`MailboxScreen.kt:348`). Loads the entire folder as `List<Message>`. - **Unified search:** `observeUnifiedFolderSummaries` (`app/src/main/kotlin/org/libremail/data/local/dao/MessageDao.kt:52`) — its own KDoc notes it "materializes the *entire* unified inbox (~thousands of rows) on every emission." - **Per-account search:** same whole-folder path. This re-introduces the whole-list-in-memory cost that #124 removed, the moment the user switches to a single account or runs a search. **Fix:** add a Room `PagingSource` variant for the per-account folder (mirroring `pagingUnifiedFolderSummaries` in `MessageDao`), plus a paged/limited search, and wire them through `MailboxViewModel` + `MailboxScreen` the same way the unified browse list is paged. Reuse the shared `PagingConfig` (see #1). Keep the lazy `key`s and the load-state handling consistent with the unified list.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: JMR-dev/LibreMail#214