The motivation behind this API is to provide finer control of the scheduling of javascript, so that developers have the power to make the kinds of decisions you’re describing.
Because input events are unpredictable, it probably doesn’t make sense to postpone necessary rendering work on the off chance that an input event will arrive. In the worst case (i.e., input event arrives right after rPAF does some heavy lifting), your code will have done some unnecessary rendering work that gets invalidated before it’s ever displayed. In the best case, you will have smooth rendering and animations because you always get the rendering work done with time to spare.
If you were trying to optimize for both smooth rendering and prompt response to input, you might use an idiom like this:
function runLoop() {
requestPostAnimationFrame(() => {
// Get a head start on essential rendering work
doEarlyRenderingWork();
requestAnimationFrame(() => {
// Last-minute adjustments for late-arriving events
doLateRenderingWork();
// Re-schedule for every frame.
runLoop();
});
});
}
element.addEventListener('click', evt => {
if (requiresHeavyLifting(evt)) {
// Rather than risk missing a rendering deadline and
// janking, postpone handling the input event until
// the next frame.
queueEarlyRenderingWork(evt);
} else {
// Respond to the event in the current frame
queueLateRenderingWork(evt);
}
});
Ideally, if an input event must be handled ASAP, and the event will cause a visual update, then the page would be structured such that the visual response will be limited to compositor-driven effects that won’t invalidate layout (transform, opacity, z-index). Those kinds of changes can be applied during rAF without missing a rendering deadline. Where that’s not possible, then the developer must pick their poison: respond to the input event a frame late, or risk janking the display.
rAF-aligned input events are the continuous-type events that tend to arrive in streams (e.g. mousemove). In chromium, those events are not delivered as they arrive; instead, they are merged and delivered just prior to running rAF handlers. For these events, it is all the more important to use compositor-driven effects, since there is little runway for doing long-running work prior to rendering.
Hope that helps.