Copyright © 2015 W3C® (MIT, ERCIM, Keio, Beihang). W3C liability, trademark and document use rules apply.
This document defines an API web page authors can use to write script-based animations where the user agent is in control of limiting the update rate of the animation. The user agent is in a better position to determine the ideal animation rate based on whether the page is currently in a foreground or background tab, what the current load on the CPU is, and so on. Using this API should therefore result in more appropriate utilization of the CPU by the browser.
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.
Beware. This specification is no longer in active maintenance and the Web Performance Working Group does not intend to maintain it further. See HTML instead.
This document is the 22 September 2015 Working Group Note of the Timing control for script-based animations specification.
Comments about this document may be sent to public-web-perf@w3.org (archived) with [RequestAnimationFrame] at the start of the subject line but really, see the HTML specification instead.
This document is produced by the Web Performance Working Group.
Publication as a Working Group Note does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
This document is governed by the 1 September 2015 W3C Process Document.
This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
This section is informative.
Animations in web browsers come in two forms: native, declarative ones, such
as the <animate>
element in SVG, and those that are implemented
in script. These script-based animations are most often performed by scheduling
a callback using setTimeout
or setInterval
and making
changes to the DOM to effect the animation in that callback.
A disadvantage of this approach is that the author of the animation script has
no idea what the ideal frequency for updating their animation is. Instead, the
easiest way forward for the author is to simply call setTimeout
with
a very small value, which in practice will be clamped to some minimum time like
10ms anyway. It likely won’t be the case that 100 updates per second are required
for the animation, especially if the page is in a background tab or the browser
window is minimized.
The API described in this document allows script authors to request the user agent schedule an animation frame update. The user agent is in a better position to determine how many frames per second to allocate to all of the animations running in the entire browser. If there are many animations active, the user agent can select a frame rate such that all of the animations will run as smoothly as possible. If the page is not currently visible, animations on that page can be throttled heavily so that they do not update often and thus consume little CPU power.
Here is an example of using the API to write a script-based animation.
<!DOCTYPE html> <title>Script-based animation using requestAnimationFrame</title> <style> div { position: absolute; left: 10px; padding: 50px; background: crimson; color: white } </style> <script> var requestId = 0; function animate(time) { document.getElementById("animated").style.left = (time - animationStartTime) % 2000 / 4 + "px"; requestId = window.requestAnimationFrame(animate); } function start() { animationStartTime = window.performance.now(); requestId = window.requestAnimationFrame(animate); } function stop() { if (requestId) window.cancelAnimationFrame(requestId); requestId = 0; } </script> <button onclick="start()">Click me to start!</button> <button onclick="stop()">Click me to stop!</button> <div id="animated">Hello there.</div>
Everything in this specification is normative except for diagrams, examples, notes and sections marked as being informative.
The keywords “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY” and “OPTIONAL” in this document are to be interpreted as described in Key words for use in RFCs to Indicate Requirement Levels. [RFC2119]
The IDL fragment in section 4 of this specification MUST be interpreted as required for conforming IDL fragments, as described in the Web IDL specification. [WEBIDL]
This specification defines a single conformance class:
This specification references interfaces and types from a number of other specifications:
Document
[DOM]Window
[HTML5]DOMHighResTimeStamp
[HighResolutionTime]Associated with every Document
is an animation frame request callback list,
which is a list of <handle, callback> tuples.
handle is an integer that uniquely identifies the entry in the list.
callback is a FrameRequestCallback
object. Initially, the
animation frame request callback list
for a Document
is empty.
A Document
is said to have active animations
whenever it has a non-empty animation
frame request callback list.
The partial interface in the IDL fragment below is used to expose the
requestAnimationFrame
operation on the Window
object. In the definition of requestAnimationFrame
below, references to the
Document
object are to be taken to be references to the Window
object’s active document. [HTML5]
partial interface Window { long requestAnimationFrame(FrameRequestCallback callback); void cancelAnimationFrame(long handle); }; callback FrameRequestCallback = void (DOMHighResTimeStamp time);
The requestAnimationFrame
method is
used to signal to the user agent that a script-based animation
needs to be resampled. When requestAnimationFrame(callback)
is called, the user agent MUST schedule a script-based animation
resampling by appending to the end of the animation frame request callback list
an entry whose handle is a user-agent-defined integer greater than zero that uniquely identifies the entry in the list and
whose callback is callback
.
Each FrameRequestCallback object has a cancelled boolean flag. This flag is initially false and is not exposed by any interface.
requestAnimationFrame
only schedules
a single update to the script-based animation. If subsequent animation frames are needed, then
requestAnimationFrame
will need to be called
again from within the callback.
Also note that multiple calls to requestAnimationFrame
with the same callback
(before callbacks are invoked and
the list is cleared) will result in multiple entries being in the list with that same callback,
and thus will result in that callback being invoked more than once for the animation frame.
The cancelAnimationFrame
method is
used to cancel a previously made request to schedule an animation frame update. When cancelAnimationFrame(handle)
is called,
the user agent MUST set the cancelled flag to true for the
callback registered on this Document whose handle is handle
. The cancelled
flag is set whether the callback is in a animation frame request callback list or not.
If there is no callback with the given handle, then this function does nothing.
cancelAnimationFrame
might be called for an entry
in the Document
’s
animation frame request callback list or in
the sample all animations operation’s temporary list. In
either case the entry’s cancelled flag is set to true so that the callback does not run.
The invoke callbacks algorithm:
The expectation is that the user agent will run tasks from the animation task source at at a regular interval matching the display's refresh rate. Running tasks at a lower rate can result in animations not appearing smooth. Running tasks at a higher rate can cause extra computation to occur without a user-visible benefit.
This section is informative.
The editors would like to thank the following people for contributing to this specification: Boris Zbarsky, Jonas Sicking, Robert O’Callahan.
This specification was written based on the mozRequestAnimationFrame
feature implemented in Firefox.