mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
The T2 realization-compensation writer in useAnchoredScroll.ts was near-perfect on Chromium and near-ineffective on WebKit (39 felt lurches up to 204px per 30-swipe momentum pass). Root cause: the reading-anchor baseline was snapshotted in the scroll handler, on the assumption that scroll fires before ResizeObserver in the same frame. That holds on Chromium; WebKit dispatches scroll asynchronously off its scrolling thread and coalesces it, so under momentum the RO consumed a stale snapshot and the drift measurement folded the user's own wheel delta into the correction — the writer fought the wheel. Make the path independent of scroll-event timing: - Baseline the reading anchor per-rAF (single writer, module rAF loop), not per-scroll-event. rAF runs before layout/RO on every engine, so the baseline is the freshest pre-reflow read cross-engine. - Compute the correction scroll-invariantly from the anchor row's document position (scrollTop + topOffset), which changes only when content above reflows — isolating the layout shift from user scroll. Extracted as computeAnchorCorrection(), unit-tested for sign and invariance. - Write an absolute scrollTop target from this frame's own late reads, not scrollBy against a possibly-stale offset (blunts the write-race). - Staleness is a first-class SKIP: if scroll moved more than COMPENSATION_SCROLL_SKIP_PX since baseline, momentum is in flight and the reads may straddle a compositor commit — skip and let the next quiet frame catch it. Under-correcting is invisible; fighting the wheel is the lurch. - Derive at-bottom vs mid-history from synchronous geometry (isAtBottomNow) in both the rAF sampler and the RO callback, never from the scroll-maintained anchorRef, so the branch and the baseline can't disagree under momentum. - Pick the reading anchor a safe margin below the fold (READING_ANCHOR_SAFE_MARGIN_PX) so it never sits inside the realization band it's meant to measure against. Co-authored-by: Dawn (sprout agent) <c6237ef84fa537c78dcee78efd2d4e59f728859c7f194da42ac51ededfa0be05@sprout-oss.stage.blox.sqprod.co> Signed-off-by: tlongwell-block <109685178+tlongwell-block@users.noreply.github.com>
Buzz
Desktop chat shell with:
- Tauri + React + TypeScript + Vite
- Tailwind CSS
- shadcn/ui-ready shared components
- Biome (lint/format/check)
- Feature-driven frontend structure
Scripts
pnpm dev- run the web frontendpnpm tauri dev- run the desktop apppnpm build- typecheck and build frontendpnpm typecheck- TypeScript checkspnpm lint- Biome lintpnpm format- Biome format (write)pnpm check- Biome check
Structure
src/shared- reusable app-wide code (ui,lib,styles)src/features- feature modules (vertical slices)src/app- top-level app composition