Frame Budget in Browser Rendering
Frame budget is the time available to produce each frame at a target refresh rate. Staying within that budget helps animations and interactions remain visually smooth.
At 60 Hz, the browser has about 16.67 milliseconds per frame. At higher refresh rates, the available time is smaller: 120 Hz allows about 8.33 milliseconds, while 144 Hz allows about 6.94 milliseconds. The budget covers the work needed to get a frame ready for display, not just JavaScript execution.
A frame can involve JavaScript, style calculation, layout, painting, and compositing. Some work may be skipped or reused depending on what changed, so the exact pipeline varies by update. Expensive synchronous JavaScript can delay subsequent rendering work and cause missed frames.
When rendering work exceeds the available time repeatedly, users may see dropped frames, stutter, or delayed visual updates. A single expensive frame can also be noticeable during an interaction, even if the average frame time is low.
For frontend performance, common strategies include reducing unnecessary work, avoiding forced synchronous layout, batching DOM updates, and moving non-urgent work away from critical rendering periods. APIs such as `requestAnimationFrame` let animation updates align with the browser's rendering cycle.
Key points
- At 60 Hz, one frame has roughly 16.67 ms of time.
- Higher refresh rates impose smaller frame budgets.
- JavaScript is only one part of the rendering pipeline.
- Repeatedly exceeding the budget can cause jank and dropped frames.
- Measure frame time and rendering work rather than optimizing JavaScript in isolation.
Interview questions
What is a frame budget, and why does it matter for frontend performance?
A frame budget is the approximate time available to prepare one frame before the next display refresh. At 60 Hz, that is about 16.67 ms. If rendering work repeatedly takes longer than that, frames can be missed and the UI may appear to stutter. The budget includes more than JavaScript, such as style, layout, paint, and compositing work.
Why is optimizing JavaScript alone not sufficient to maintain smooth rendering?
JavaScript can trigger or delay other rendering work, but it is not the entire rendering pipeline. Style calculation, layout, painting, and compositing can also consume significant time. A small JavaScript function can still cause expensive downstream work if it changes many elements or invalidates layout. Performance analysis therefore needs to consider the complete frame.
How would you reduce frame-time problems in an animation?
First, profile the animation to determine whether JavaScript, layout, paint, or another stage is the bottleneck. Then reduce unnecessary DOM work, batch mutations, avoid layout thrashing, and prefer properties that can often be handled efficiently by compositing. Animation updates should generally be coordinated with `requestAnimationFrame`. The goal is to reduce the amount of work on the critical path rather than blindly reducing JavaScript lines.
Why does a 120 Hz display require tighter performance than a 60 Hz display?
The display refreshes twice as often, so the interval between refreshes is half as long. A 60 Hz target gives about 16.67 ms per frame, whereas 120 Hz gives about 8.33 ms. The rendering pipeline therefore has less time to prepare each frame. Code that appears acceptable at 60 Hz can miss deadlines at 120 Hz if its frame work is too expensive.
What is the relationship between long tasks and missed frames?
A long main-thread task can occupy the browser when it needs to perform work for a new frame. If that work cannot finish before the relevant rendering deadline, the frame may be missed. Long tasks are therefore an important source of jank, although rendering bottlenecks can also occur without a single obvious JavaScript long task. Profiling should identify which stage is consuming the frame time.