From 9b49a11710dfb9ded1cf3297696c32ffc64bf7e8 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Sat, 26 Sep 2026 07:31:09 -0700 Subject: Feed: only the rows near the viewport are in the DOM, however far you scroll. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A long scroll left hundreds of rows mounted, and every repaint (a zap count, a profile landing, the thirty-second sync) rebuilt and diffed all of them — the slowdown deep in the feed. Rows beyond two and a half screens either side of the viewport are now replaced by a spacer at their measured height, so the page keeps its length (scrollbar, Back, arrival anchoring behave as before) while a repaint touches a few dozen rows. After svelte-virtual-list: measure after paint, estimate unmeasured rows at the running average, hold the reader's row still when a measurement corrects an estimate. Applies to the profile notes list too. Tests: feed-window-dom (120 posts, 27,800px page, 12–24 rows mounted, anchor held, spacers both sides); feed-live looks at the top after scrolling up; the moderation test's stub relay no longer lets real posts in. Co-Authored-By: Claude Fable 5.1 --- tools/feed-live-test.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'tools/feed-live-test.js') diff --git a/tools/feed-live-test.js b/tools/feed-live-test.js index 7732045..9f98fde 100644 --- a/tools/feed-live-test.js +++ b/tools/feed-live-test.js @@ -287,7 +287,10 @@ try { await away(() => Array.from({ length: 25 }, (_, i) => signed('LONG AWAY ' + (i + 1), 0))); const a3 = await rowAt(heldLong.text); check('many new posts still preserve the reading position', !!a3 && Math.abs(a3.top - heldLong.top) <= 2, JSON.stringify({ heldLong, a3 })); - check('...with the newest posts above and a notice', /LONG AWAY 1\b/.test(await topRow()) && !!(await page.$('.feed-new-pill')), (await topRow()).slice(0, 40)); + check('...with a notice', !!(await page.$('.feed-new-pill'))); + // the page top is not mounted from down here (windowing): go up to look + await page.evaluate(() => window.scrollTo(0, 0)); await sleep(600); + check('...and the newest posts at the top', /LONG AWAY 1\b/.test(await topRow()), (await topRow()).slice(0, 40)); check('no page errors', errs.length === 0, errs.slice(0, 2).join(' | ')); } finally { await browser.close(); server.stop(true); } -- cgit v1.2.3