Company-mode UIs became unusably slow once work items and transcripts
grew. Three presentation-layer fixes, none touching work progression:
- App.tsx: buffer assistant_delta/thinking_delta store writes per task
and flush every 80ms instead of once per token; any non-delta event
for the same task flushes first so draft/clearDraft ordering is
byte-identical. The unconditional per-event setUiTick (whole-app
re-render per websocket event) is now a 300ms trailing throttle.
- PhaserGame: display:none does not stop requestAnimationFrame, so the
office scene kept burning CPU on every other page. The loop now
sleeps when the office page is hidden and wakes (with a parent-bounds
refresh) on return; bridge writes stay synchronous so no state is lost.
- Kanban collab_sync debounce 0.2s -> 1.5s: the broadcaster is a
trailing coalescer, so the final board state still always ships; each
fire is a full-project snapshot build, which at 5/s dominated backend
CPU on large projects. CommsPanel poll 8s -> 30s (comms_state_dirty
push already drives freshness) and its interval no longer pins a
stale onRefresh closure.
Verified: tsc + vite build, App.test.tsx / workItemSessions structural
tests, backend suites (company_review_flow incl. debounce push test,
kanban_push_runtime, actor_runtime_company_mode, task_mode_contract,
work_item_transition — 119 green), and canvas_smoke e2e against a real
server with zero console errors.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>