Smooth out streaming text
Buffer uneven chunks and reveal them at a steady rate.
Sam Selikoff@samselikoffHacking on a useBufferedText hook and <AnimatedScroller> component for streaming text. Goal is to have smoother output regardless of the rate + chunk size of the stream.
1 · Same stream, two displays
Both panes get identical chunks. Raise jitter and replay.
Append each chunkBad
Biggest jump
0 charsLongest pause0msBuffer, steady revealGood
Biggest jump
0 charsLongest pause0msBuffer0const queue = []; // chunks land here as they arrive
let shown = 0;
onChunk((text) => queue.push(...text));
function frame() {
// reveal faster when the buffer is large, so it never lags far behind
const n = Math.max(1, Math.round(queue.length / 18));
shown += queue.splice(0, n).join("");
render(shown);
if (queue.length || streaming) requestAnimationFrame(frame);
}
Why it matters, pros and cons
Why it matters
Network chunks are uneven, so raw output stalls and then lurches. A buffer decouples arrival from display.
Pros
- Text flows at the same pace whatever the chunk size or network jitter.
- Adaptive speed catches up after a burst instead of drifting behind.
- Works with any stream: the buffer sits between the transport and render.
Cons
- The reader sees text slightly after it arrives, a few hundred ms at most.
- Needs a per-frame loop and care to stop it once the buffer drains.
- Reduced motion users should get whole chunks, not a character race.