How streaming motion works

dsh-smooth-stream separates two jobs that are often mixed together: deciding how much new content to reveal, and moving the viewport as that content changes height.

dsh-smooth-stream 将两件事分开处理:决定每次呈现多少新内容,以及内容高度变化时如何移动视口。

1. Reveal follows queue pressure

Model output does not arrive at a stable rate. Small chunks should keep a measured cadence; a growing queue has to catch up. The reveal engine calculates a speed from the current backlog and carries fractional character debt between frames. At 60Hz, the same function produces these decisions:

Pending charactersTarget speedCharacters this frame
8101.4 chars/s1
32154.7 chars/s2
128456.0 chars/s7
512+600.0 chars/s10

积压少时保持从容节奏,积压增加后逐步加速;速度有上限,避免一次把长段内容倾倒到页面。

2. One spring owns the vertical motion

Each layout change updates the target height. A damped spring carries its position and velocity into the next frame, so new wraps, code blocks, tables, and tool results feed one continuous trajectory. Physical time is clamped after a long main-thread stall instead of replaying the entire missed interval in one paint.

The same initial lag settles in nearly the same wall-clock time at 60Hz and 120Hz:

Initial lag60Hz120Hz
16px750ms725ms
48px883ms858ms
96px967ms950ms
192px1067ms1033ms

刷新率改变时帧数会变化,但实际运动时间接近,因此 60Hz 与 120Hz 下保持相似手感。

3. Reveal and follow share pressure

The follower keeps a small amount of measured room for the next wrap. When safe visual lag fills, it scales reveal pressure from 1.0 toward 0.55. This slows incoming layout growth instead of letting text outrun the scroll spring.

Lag inside a 48px capacityReveal scale
0–12px1.000
24px0.775
36–48px0.550

Reproduce the benchmark

git clone https://github.com/Laplace-bit/dsh-smooth-stream.git
cd dsh-smooth-stream
pnpm install
pnpm benchmark

The checked-in result was recorded on Apple M5, Node.js v22.22.1, macOS arm64. The median of seven measured runs was 47.3 million queue decisions/s and 89.3 million spring decisions/s after two warm-up runs.

Scope: this microbenchmark measures pure TypeScript decisions only. It does not measure React commits, Markdown parsing, browser layout, paint, device thermals, or network time. Those require a Performance trace in a real DeepSeek Harness session. The high operation counts only show that the two math functions are not the likely UI bottleneck.

Raw result: 2026-08-20-apple-m5.json. Benchmark source: stream-engine.ts.

What should be measured next

The useful end-to-end follow-up is a shared Chrome Performance trace for the same long Markdown fixture on desktop and a lower-power mobile device. That trace should report scripting, style/layout, paint, dropped frames, and the exact Harness/plugin versions. Until that exists, this project will not publish a broad “X% faster” claim.