The event loop, one frame at a time
Sixteen milliseconds, and everything that has to fit inside them before the screen updates.
At 60 frames per second the browser has about 16.7 ms to run your tasks, process input, run animation callbacks, recalculate style, lay out, paint and composite. Miss the budget and the frame is simply not drawn.
The ordering is fixed and worth memorising, because it explains almost every animation bug you will ever file.
- Tasks first, one at a time, in the order they were queued.
- Then microtasks, drained completely, which is why a promise loop can starve rendering entirely.
- Then requestAnimationFrame callbacks, then style, layout, paint, composite.
Microtasks do not yield
An unbounded chain of promises will never let a frame render. If a loop must run, break it with setTimeout, not with another then.
Comments
3 Newest firstWould love a follow-up on where scheduler.yield fits into this now that it is shipping.
It is on the list. Short version: it does what the setTimeout trick does, without the four-millisecond floor.
The microtask starvation point explains a bug I filed against a framework last year and never got to the bottom of. It was our own promise loop.