| |
|
|
|
|
|
| |
of it. "When I flick to scroll, it's not getting up to speed very quickly, and clicking around in the app feels a bit sluggish at times" (Adam, 2026-11-07). Measured on his Pixel 9 in the installed PWA: idle is quiet (0.16 s of script in 10 s), but three real flicks through Following spent 1.7 s of 9 on the main thread, frames up to 200 ms, and the work was the avatar thumbnailer finishing faces as they scrolled in: a synchronous canvas.toDataURL WebP encode per face (229 ms), the profile cache JSON.stringified twice per half-second flush (once just to measure it, up to ~2 MB with thumbnails), and a whole-page repaint per finished face that changes nothing on screen (feed rows keep the face they were admitted with). Now: the crop, resize and encode happen off the main thread (createImageBitmap with resizeWidth/Height, OffscreenCanvas.convertToBlob, FileReader), with the old canvas path as the fallback; a finished face is recorded once the page settles; scheduleRepaint holds while a finger is down or the page scrolled in the last 200 ms (at most 1.5 s), and the profile flush likewise (at most 5 s, forced on an account switch) and sizes the blob by summing rows instead of stringifying it. Tests: the create flow's heads-up / passphrase / check steps from earlier today broke every test that made a wallet by waiting for the words and clicking "Skip verification"; tools/puppeteer.js exports seedWords() and skipSeedCheck() and the 96 tests use them. room-faces and avatar-profile fail the same way on 8858591 (row.hover, scrollIntoView), before today's changes
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VMan6Ts5Tktega8VbLg31q
|
|
|
ahead of running out.
Appetite: the screens the reader has scrolled by their own hand over the last ten seconds (a scroll within a moment of an input — a page held still under an insert above is not travel). Five screens in that time is someone flying through: the page grows from ten posts to twenty, thirty, forty at once, the lead above the foot of the feed at which the next page is asked for grows the same way (from four screens to sixteen), and each relay round trip asks for proportionally more (30 → up to 100 per chunk). Standing still ten seconds brings the ordinary page back. (Adam, 2026-10-16: "could we load posts faster if it seems like the user is scrolling a lot? … try always loading more posts and loading them sooner when we're further away from the bottom".)
The relays run ahead of the rows now. The older page used to be asked for only once every post in hand was on screen, and shown only once the whole pass had answered — so the reader who reached the end of what we held waited a relay round trip, up to the five seconds the slowest relay in the pass is given. A pass for older posts (fetchOlderAhead) starts as soon as what we hold beyond the shown rows thins to a page or two (more with the appetite), its rows warming at the door while the reader is still on the posts before them; the showing step (loadOlderFeed) takes from hand and only waits on a pass already underway when the hand is empty. The in-memory window keeps up to fifty posts beyond the shown rows for that (it kept one page).
tools/feed-appetite-test.js: an ordinary pace pages ten at a time with the relays asked while posts are still in hand, so the end of what was held finds more already there; two flights of eleven screens page twenty then thirty at once, from further above the foot than the ordinary lead, with the relays asked for 60 and 90 per trip; ten seconds still and the page is ten again. The .notes-feed card carries data-shown / data-held for it. Pre-existing failures unchanged: feed-live "picture already decoded" and feed-streaming "tap reveals the oldest ready new post" fail on a clean worktree of ca3b61e too; feed-stability's two known ones.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01J1Kon8bxJoHRpJdSzshCkp
|