mirror of
https://github.com/getpaseo/paseo.git
synced 2026-11-11 02:46:29 +00:00
Two causes, both reproduced on a clone of a real long thinking-partner chat
(replies and thinking rows several screens tall, GFM tables).
1. The window lowered in e42771970 (initial 2 / batch 2 / window 5) holds only
two or three tall rows, so a fling outruns the mounted range and the viewport
crosses unmounted rows: 65 blank frames over a 4,152-frame traversal. Keep the
small initial render that bounds cold-open measurement, but refill a window of
10 in batches of 10: 0 blank frames over 4,347, p95 25 ms.
2. Scroll-to-bottom from deep history animated across every row in between,
which no finite window can mount in time: 9 blank frames (~150 ms) per jump.
Animate only when the current offset is within the bottom-side overscan,
otherwise jump instantly. Near-bottom jumps still animate. Web already does
not animate this jump.
Cold open on the same chat is unchanged (first content 569 -> 568 ms); the
deeper window costs first-scroll acknowledgement (2.58 -> 2.94 s in a debug
build).
35 lines
1.2 KiB
TypeScript
35 lines
1.2 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { shouldAnimateNativeScrollToBottom } from "./native-scroll-animation";
|
|
|
|
describe("native scroll-to-bottom animation", () => {
|
|
it("jumps across unmounted history instead of animating through blank rows", () => {
|
|
expect(
|
|
shouldAnimateNativeScrollToBottom({ offsetY: 60_000, viewportHeight: 600, windowSize: 10 }),
|
|
).toBe(false);
|
|
});
|
|
|
|
it("keeps near-bottom movement eligible for animation", () => {
|
|
expect(
|
|
shouldAnimateNativeScrollToBottom({ offsetY: 300, viewportHeight: 600, windowSize: 10 }),
|
|
).toBe(true);
|
|
});
|
|
|
|
it("bounds travel by the bottom-side overscan, not the whole window", () => {
|
|
expect(
|
|
shouldAnimateNativeScrollToBottom({ offsetY: 2700, viewportHeight: 600, windowSize: 10 }),
|
|
).toBe(true);
|
|
expect(
|
|
shouldAnimateNativeScrollToBottom({ offsetY: 2701, viewportHeight: 600, windowSize: 10 }),
|
|
).toBe(false);
|
|
expect(
|
|
shouldAnimateNativeScrollToBottom({ offsetY: 1500, viewportHeight: 600, windowSize: 5 }),
|
|
).toBe(false);
|
|
});
|
|
|
|
it("does not animate before the viewport has been measured", () => {
|
|
expect(
|
|
shouldAnimateNativeScrollToBottom({ offsetY: 0, viewportHeight: 0, windowSize: 10 }),
|
|
).toBe(false);
|
|
});
|
|
});
|