Why screen recordings of web apps stutter, and how to film one without it
A screen recording of a web app often looks slightly wrong: a scroll that hitches, a zoom that goes soft. We measured why, on the same 20 seconds recorded five ways, and what fixes it.
The test
One scripted scenario, 20 seconds long: typing, a page change, a drawer that springs open, hover previews, a toast, scrolling, a button press. The window was 1600x900, in headless Chromium, on a laptop with a Ryzen 5 4600H.
To measure pacing we put a small bar at the bottom of the page that moves at a constant speed. At a true 60 frames a second it advances exactly 5 pixels per frame. Any frame where it has not moved is a repeated frame, and a run of them is a freeze you can see.
What we measured
| Method | Distinct frames per second | Repeated frames | Longest freeze |
|---|---|---|---|
| Playwright's built-in video | 20.2 | 66% | 933 ms |
| Playwright screencast (JPEG frames) | 33.7 | 44% | 283 ms |
| Chrome screencast (PNG frames, forced repaints) | 32.3 | 46% | 333 ms |
| Frame by frame, 1x | 54.9 | 8.6% | 17 ms |
| Frame by frame, 2x pixel density | 54.9 | 8.6% | 17 ms |
In the last two rows the leftover repeats never last more than one frame. They come from the measuring bar's own scheduling, and you cannot see them.
Why real-time recording stutters
A real-time recorder asks the browser to do two jobs at once on the same processor: draw the page, and capture and encode what it drew. When the page gets busy, with an animation, a large repaint or a script, the capture falls behind and the recorder repeats the last frame it has. That is the hitch.
A faster machine helps and guarantees nothing. The moments you most want smooth, a zoom or a transition, are exactly the ones where the page is working hardest.
Sharpness is lost quietly
To zoom into a recording without it going soft, you need more pixels than you show: a capture at twice the pixel density. In our test, asking for 2x in real time returned ordinary 1x frames without an error. Forcing 2x did produce true 3200x1800 frames, at 12 a second.
Defaults work against you too. Playwright's documentation says its video size "defaults to the viewport size scaled down to fit 800x800". A 1600x900 window recorded with the defaults comes out at half its width.
The fix: one frame at a time
Chrome has an experimental command in its DevTools Protocol, HeadlessExperimental.beginFrame, that draws a single frame on request and can hand back a screenshot of it. Pair it with a virtual clock, so that the page's timers, dates and animation frames advance by exactly one sixtieth of a second per frame, and the recording no longer depends on how fast the machine is. A slow computer takes longer. The film is the same.
The trap we fell into
Our first frame-by-frame take had a blank main area. With the browser's own frame clock stopped, CSS transitions and Web Animations stop too, so the page's fade-in never ran and the content stayed invisible.
The fix is to step every running animation forward by hand on each frame, from the virtual clock. Remotion, which renders videos from React, documents the same principle for its own renderer: animations must "run purely off the value of useCurrentFrame()", because anything that runs on its own clock breaks when frames are not drawn in real time.
What it costs
Time. On that laptop, frame-by-frame capture produced about 6 frames a second at 1x and about 1.6 at 2x. The 24-second take at 2x took 15 minutes. A 90-second video is 5,400 frames, roughly an hour on the same machine, less on a server, and less again if the take is split across several machines.
For a demo video that trade is easy. Nobody is waiting on the recording live, and the result has to look perfectly smooth.
What you can do with an ordinary recorder
These are our suggestions from the measurements above, not separate tests:
- Close everything else. The recorder and the page are competing for the same processor.
- Record at the size you will publish, and check the output's real dimensions. A default may have scaled it down.
- If you plan to zoom, capture at 2x and confirm you got it, by opening a frame and counting pixels.
- Keep animations short during the take, or cut around the moments that hitch.
Common questions
Why is my screen recording choppy when my app runs smoothly?
Because the recorder captures and encodes on the same processor that draws the page. When the page is busy the capture falls behind and repeats frames. In our test of one 20-second scenario, three real-time methods delivered 20 to 34 distinct frames a second, with freezes of up to 933 milliseconds.
What is frame-by-frame or deterministic capture?
Instead of recording in real time, you ask the browser to draw one frame, save it, advance a virtual clock by one sixtieth of a second, and repeat. The result does not depend on the machine's speed. In our test it gave 54.9 distinct frames a second and no freeze longer than 17 milliseconds.
Does capturing at 2x make a difference?
Only if you zoom. A 2x capture has four times the pixels, so a zoom to 2x still shows one source pixel per screen pixel. In real time, a 2x request quietly returned 1x frames in our test, and forcing 2x dropped to 12 frames a second.
Is frame-by-frame capture slower?
Yes. On a laptop it produced about 6 frames a second at 1x and 1.6 at 2x, so a 24-second take at 2x took 15 minutes. It costs rendering time, not quality.
Sources
- Our own measurements, September 25, 2026: one 20-second scripted scenario at 1600x900 in headless Chromium on a Ryzen 5 4600H laptop, recorded five ways, pacing measured from a bar moving at constant speed. Summarised in the Framefly production log.
- HeadlessExperimental domain, Chrome DevTools Protocol. The
beginFramecommand that draws one frame on request, with an optional screenshot. - Videos, Playwright documentation. The default video size, scaled down to fit 800x800.
- Flickering, Remotion documentation. Why animations must be driven by the frame number when frames are not rendered in real time.
Framefly films your app for you. Give it a demo account and a brief; it writes the video, shows you the plan, then films it. It launches on October 28, and a few apps are being filmed before that.
Apply for the betaFramefly films your app for you. Give it a demo account and a brief; it writes the video, shows you the plan, then films it. The first video is free.
Make your first video