July 3, 2026

Playing a dense timeline without stutter

A 25-clip project stuttered a few seconds into playback. It was not decoding speed. We had mounted every video in the project at once.

The video composer plays back in the browser using real <video> elements composited with CSS. That's fast, simple and good at seeking, right up until you ask it to play a timeline with two dozen clips on it.

The symptom

A 25-clip project played for a couple of seconds and then stuttered badly. Short projects were completely fine. We suspected decode cost, then the network, and both turned out to be innocent.

What was actually happening

Playback kept a warm-up window so a clip would be ready before the playhead got to it. That window was sixty seconds long. In a project shorter than sixty seconds, "every clip starting within the window" quietly means every clip in the project: twenty-four live decoders, twenty-four buffers and twenty-four compositor layers, all at once. And each of them re-rendered on every tick of a 60 Hz clock.
The bit worth stealing: a lookahead measured in seconds silently becomes "everything" the moment your content is shorter than the lookahead. Bound the count, not just the horizon.

The fix

Selection is now explicit and bounded: the clips under the playhead, plus the nearest few that start within a short lookahead, plus anything just past its end so a cut doesn't blink. On the same 24-clip timeline:
BeforeAfter
Peak videos mounted248
Mean videos mounted15.46.1
Warm-up lead before a clip goes active stayed comfortable at over two seconds, so nothing regressed into blank frames.

The trap we fell into first

Our first attempt gated playback on the clips under the playhead alone. That broke mid-timeline playback in a way that was maddening to track down: video went dark a few seconds in while audio and text carried on, because only video depends on a mounted element. The gate has to cover what's coming, not only what's here.

And one that's easy to miss

None of this is verifiable in a backgrounded tab. Browsers throttle animation frames when a tab is hidden, so the clock never ticks and the timecode sits at zero looking broken. Every measurement here was taken with the tab in front.