You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
700ms streaming tick re-renders all three main panes #91
Only Markdown (Markdown.tsx:74) and MessageBlock (ThreadView.tsx:385) are memoized. Every thread:updated tick (tickMs: 700, electron/main.js:278) maps a new threads array in useCoder.ts:448-452, so App re-renders Sidebar + ThreadView + AgentsPanel (~7,400 lines of components) per tick, on top of auto-animate in the sidebar. Fine on one thread; with five concurrent streams it's a constant render storm.
Fix: memoize the panes and split the streaming detail subscription from the list subscription, so a streaming thread doesn't re-render the whole shell.
Fixed in 96b984c on coder/700ms-streaming-tick-re-renders-all-thre-f41da5.
patchThreadList (src/threadPatch.ts) keeps the array and row identity when the pushed summary did not move, so a tick that only grew the transcript never touches the list.
mergeThreadPatch keeps the previous thread/usage objects when structurally equal, so a rebuilt-but-identical object no longer invalidates panes or effects keyed on them.
Sidebar, ThreadView and AgentsPanel are memo'd; App holds every handler stable for that to bite. ThreadView takes a resolved handoffSource and AgentsPanel a rosterKey instead of the whole list, whose identity churns by design.
Net: a background stream costs nothing while it is quiet, and one sidebar row re-render when it appends; the open thread re-renders ThreadView only.
Checks: npm run typecheck, npm run build, npm run test:renderer (700/700) all green. New unit coverage in test/threadPatch.test.ts for the identity guarantees.
Activity
currentbits commentedon Aug 16, 2026
Fixed in
96b984concoder/700ms-streaming-tick-re-renders-all-thre-f41da5.patchThreadList(src/threadPatch.ts) keeps the array and row identity when the pushed summary did not move, so a tick that only grew the transcript never touches the list.mergeThreadPatchkeeps the previousthread/usageobjects when structurally equal, so a rebuilt-but-identical object no longer invalidates panes or effects keyed on them.memo'd; App holds every handler stable for that to bite. ThreadView takes a resolvedhandoffSourceand AgentsPanel arosterKeyinstead of the whole list, whose identity churns by design.Net: a background stream costs nothing while it is quiet, and one sidebar row re-render when it appends; the open thread re-renders ThreadView only.
Checks:
npm run typecheck,npm run build,npm run test:renderer(700/700) all green. New unit coverage in test/threadPatch.test.ts for the identity guarantees.Merge pull request #120 from currentbits/coder/700ms-streaming-tick-r…