DB
- Six indices on the cards table (position+created_at, bucket_id,
parent_id, updated_at, caldav_uid, relay_uid). The /api/cards
ORDER BY position was a full-table scan + sort on every board
reload; now it's an index walk.
- PRAGMA synchronous=NORMAL (safe under WAL) + temp_store=MEMORY.
Save path
- pushCardToRelayRead and deleteCardFromRelayRead now run AFTER the
response is flushed via fastcgi_finish_request (falls back to
ignore_user_abort + flush on non-FPM setups). The user's save no
longer blocks on the relay round-trip.
- cURL timeouts dropped from 10s/30s to 5s/10s, plus a 2s
connect-timeout. Worst-case on a dead relay goes from ~160s down
to ~15s — and now that worst case is in the background anyway.
Client
- loadCards phase-2 batches bumped from 25 to 500 cards per fetch.
For 300 cards that's 1 HTTP trip instead of 12 — spinner wall time
drops from ~3s to ~0.25s.
- renderBoard() is now requestAnimationFrame-coalesced. The boot
sequence calls renderBoard from cache paint, meta paint, body
paint, and the cards.reloaded plugin hook; they used to each
trigger an innerHTML swap + layout pass. Now they collapse into
one actual render per frame. Callers that really need a sync
render (rare) can use the new renderBoardSync().
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>