Skip to content
This repository has been archived by the owner on Feb 16, 2023. It is now read-only.

Latest commit

 

History

History
42 lines (29 loc) · 3.09 KB

explainer.md

File metadata and controls

42 lines (29 loc) · 3.09 KB

AnimationFrameProvider.requestPostAnimationFrame

AnimationFrameProvider.requestPostAnimationFrame will act as a bookend to AnimationFrameProvider.requestAnimationFrame. Whereas requestAnimationFrame callbacks run just prior to the "update the rendering" step in the HTML processing model (step 10.10), requestPostAnimationFrame callbacks will run immediately after "update the rendering" (step 10.13). No other tasks or microtasks are permitted to run between "update the rendering" and requestPostAnimationFrame callbacks.

Broadly speaking, there are two situations where requestPostAnimationFrame will be useful:

Getting a head start on preparing for the next animation frame

requestAnimationFrame is useful for updating the DOM tree in preparation for the next rendering update. However, if the code in a requestAnimationFrame callback runs too long, then the rendering will not be complete in time to send new pixels to the display before the next vsync. requestPostAnimationFrame provides a way to get the earliest possible start on preparing for the next rendering update, without any possibility of the work being preempted by other less critical tasks. A typical use pattern for a continuously-animating page would be:

function animate() {
  requestPostAnimationFrame(() => {
    // Do potentially long-running work here.
    requestAnimationFrame(() => {
      // Apply final DOM and CSS updates here, if necessary.
      animate();  // Register callbacks for the next frame.
    });
  });
}

Preventing forced layouts

To ensure good performance, web developers are encouraged to avoid scripting patterns that force a synchronous layout (e.g., by modifying a CSS property and then querying the size or position of an element). However, there is currently no way for a developer to schedule code to run at a time when the page layout is guaranteed to be clean. In real world code, a common pattern to minimize the chances of forcing layout is:

addEventListener("message", event => {
  // Query layout information here.
});

requestAnimationFrame(() => {
  postMessage("*", "");
});

The requestAnimationFrame handler runs just prior to the rendering update, and there's a good chance that the message handler will be the first task to run after the rendering update. However, there is still a non-zero chance that some other code (an expired setTimeout or setInterval, or an event handler) will run after rendering, but before the message handler.

Because requestPostAnimationFrame handlers run immediately after the rendering update, before any other code, it is guaranteed that layout will be clean, and querying layout information will not force an additional synchronous layout. Caveat: if css properties are modified inside the requestPostAnimationFrame callback, then querying layout information will still force a synchronous relayout.

Similar old proposal https://www.w3.org/Bugs/Public/show_bug.cgi?id=28644