Open conversations in one request, and start them early #392

Closed
opened 2026-09-16 20:13:10 +00:00 by jcoffey-dev · 0 comments
Owner

Part of the high-latency work. Measured behind a proxy adding 125 ms each way (250 ms per round trip).

Opening a conversation: two round trips → one.

  • A thread the list already knows sends Thread/get and the missing bodies in the same tick, so both go in one request.
  • A thread it doesn't know chains Email/get off Thread/get with a back-reference. When the thread is longer than one Email/get may carry, the members are then fetched in parts.
  • Measured: the body arrived 257 ms after the press. Before this change it took two sequential requests.

Loading before the click.

  • A conversation starts loading when the pointer rests on its row for 80 ms, or as soon as a press starts.
  • Once a conversation is open, the one below it loads in idle time. Moving on with j then fetched no bodies, and the view drew immediately.
  • Loads of the same thread share one request, and an open that finds a finished prefetch sends nothing more.
  • Drafts are skipped, since they open in the composer.
  • The open conversation's bodies were already protected from eviction, so hovering over many rows can't drop them.

Folder switching.

  • The last 12 plain folder views are kept: up to 200 ids and the total for each.
  • Going back to one shows that list in the first frame while the query runs. Messages that have since moved out are dropped. Searches and new folders still start empty.
  • Measured: 29 rows in the first frame, where a skeleton used to show for a round trip.
  • Cleared on account switch.

Tests. 1,360 pass, with 7 new cases:

  • one-request open, for both a known and an unknown thread;
  • fallback for a thread that is too long for one request;
  • prefetch sharing, skip and dedupe;
  • snapshot restore and pruning;
  • search and new folders starting empty.

No new UI strings.

🤖 Generated with Claude Code

Merged 2026-09-16 as coffey-labs/ihasmail@786976312f

Rebuilt from: git history, session transcript.

Part of the high-latency work. Measured behind a proxy adding 125 ms each way (250 ms per round trip). **Opening a conversation: two round trips → one.** - A thread the list already knows sends `Thread/get` and the missing bodies in the same tick, so both go in one request. - A thread it doesn't know chains `Email/get` off `Thread/get` with a back-reference. When the thread is longer than one `Email/get` may carry, the members are then fetched in parts. - Measured: the body arrived 257 ms after the press. Before this change it took two sequential requests. **Loading before the click.** - A conversation starts loading when the pointer rests on its row for 80 ms, or as soon as a press starts. - Once a conversation is open, the one below it loads in idle time. Moving on with `j` then fetched no bodies, and the view drew immediately. - Loads of the same thread share one request, and an open that finds a finished prefetch sends nothing more. - Drafts are skipped, since they open in the composer. - The open conversation's bodies were already protected from eviction, so hovering over many rows can't drop them. **Folder switching.** - The last 12 plain folder views are kept: up to 200 ids and the total for each. - Going back to one shows that list in the first frame while the query runs. Messages that have since moved out are dropped. Searches and new folders still start empty. - Measured: 29 rows in the first frame, where a skeleton used to show for a round trip. - Cleared on account switch. **Tests.** 1,360 pass, with 7 new cases: - one-request open, for both a known and an unknown thread; - fallback for a thread that is too long for one request; - prefetch sharing, skip and dedupe; - snapshot restore and pruning; - search and new folders starting empty. No new UI strings. 🤖 Generated with [Claude Code](https://claude.com/claude-code) **Merged** 2026-09-16 as coffey-labs/ihasmail@786976312fc1 <sub>Rebuilt from: git history, session transcript.</sub>
This repo is archived. You cannot comment on issues.