What's the best way to do animations with JavaScript?
Tags: animation, javascript, webdev
Published: 2023-04-06 00:04:18

by [Aditi Agarwal](https://blog.openreplay.com/authors/aditi-agarwal)

A web designer uses web [animations](https://en.wikipedia.org/wiki/Animation), which are moving graphics, to draw in visitors and frequently persuade them to complete specific activities. They can be brief animations that draw attention to a particular piece, deliver a commercial message, or facilitate more natural user navigation. Animations, when utilized well, may bring your website to life and keep users' interest.

In this article, we'll describe several ways of doing animations with JavaScript and find what's best.

## Different ways to Animate 

Use [CSS](https://en.wikipedia.org/wiki/CSS) when [UI components](https://developer.adobe.com/commerce/frontend-core/ui-components/) have more compact, independent states. For pulling a navigation menu in from the side or displaying a [tooltip](https://en.wikipedia.org/wiki/Tooltip), [CSS Transitions](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions) and [CSS animations](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Animations/Using_CSS_animations) are perfect. 

Use [JavaScript](https://en.wikipedia.org/wiki/JavaScript) when you want extensive control over your animations. The standards-based method is the [Web Animations API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API), which is present in the majority of contemporary browsers. Real objects are provided, which are perfect for sophisticated object-oriented systems. JavaScript can also be helpful when you need to halt, pause, slow down, or reverse your animations.

If you want to manually create a whole scene, use `requestAnimationFrame`. This is a comparatively complex JavaScript technique, but it might be helpful if you're making games or want to run animations in loops.

Use CSS animations for one-shot transitions like toggling [UI element](https://www.ibm.com/docs/en/cloud-paks/cp-biz-automation/21.0.x?topic=applications-user-interface-elements) states. Animations on HTML elements via CSS can be achieved using either [CSS Animations](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Animations/Using_CSS_animations) or [CSS Transitions](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions).

## CSS Transitions
With [CSS transitions](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions), you may gradually modify an element's property values over a specified period. All we need to describe are two things to create a transition effect. One is the CSS property to which the effect will be added, and the other is the time length of the effect because if you omit the time duration, the default value will be 0 seconds, and no transition will occur.

Example:

```html
<head>
  <style>
    div {
      width: 80px;
      height: 80px;
      background: blue;
      transition: width 3s;
    }

    div:hover {
      width: 1500px;
    }
  </style>
</head>

<body>
  <h1>CSS Transition</h1>
  <p>Move the mouse over the box below to see the transition</p>
  <div></div>
</body>
```

![-](https://blog.openreplay.com/images/whats-the-best-way-to-do-animations-with-js/images/DWdNqwc.gif)


Output: A blue box with dimensions of 80px width and height will extend up to 1500px  every 3 seconds whenever it is being hovered.


## CSS Animations
By altering the element's attributes, a [CSS animation](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Animations/Using_CSS_animations) enables an element to progressively switch from one style to another. We are free to alter such characteristics as often as we choose. CSS animations comprise two parts: a style that describes the animation and a collection of [keyframes](https://en.wikipedia.org/wiki/Key_frame) that show the style's beginning and ending states as well as any potential middle points.

### Rule of @keyframes
The styles that an element will have at specific moments are stored in [keyframes](https://en.wikipedia.org/wiki/Key_frame). The [@keyframes rule](https://developer.mozilla.org/en-US/docs/Web/CSS/@keyframes) allows us to provide all of the styles, allowing us to specify which styles (element attributes) an element should have at what stage of animation. Additionally, we need to link an animation to an element for it to function. 

Note: The animation-duration parameter specifies how long an animation should last. No animation will take place if the animation-duration attribute is left blank because its default value is 0s (0 seconds).

Example:

```html
<head>
  <style>
    div {
      width: 100px;
      height: 100px;
      background-color: blue;
      position: relative;
      animation-name: example;
      animation-duration: 8s;
    }

    @keyframes example {
      0% {
        background-color: pink;
        left: 0px;
        top: 0px;
      }

      25% {
        background-color: purple;
        left: 200px;
        top: 0px;
      }

      50% {
        background-color: yellow;
        left: 200px;
        top: 200px;
      }

      75% {
        background-color: orange;
        left: 0px;
        top: 200px;
      }

      100% {
        background-color: red;
        left: 0px;
        top: 0px;
      }
    }
  </style>
</head>

<body>
  <h1>CSS Animation</h1>
  <div></div>
  <p>
    <b>Note:</b>After finishing, animation goes back to its original style.
  </p>
</body>
```
![-](https://blog.openreplay.com/images/whats-the-best-way-to-do-animations-with-js/images/hUt8sW6.gif)

Output: A box with 100px height and width will change its colors and position while going from 0% to 100% at different stages (25%, 50%, 75%, 100%) as specified by the % parameter in the code above.

Compared to implementing CSS transitions or animations, writing JavaScript animations is more difficult, but it often gives developers a lot more control. JavaScript is advised if you need to link more than three animations together. When there are delays, CSS animation sequencing gets complicated, and if the timing is off, you'll have to perform several recalculations. JavaScript makes the writing and reading of lengthy, intricate, sequential animations simpler.

In [JavaScript](https://en.wikipedia.org/wiki/JavaScript), only two functions, `setTimeout` and `setInterval`, provide [asynchronous execution](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Introducing). This implies that code can be performed without waiting for the current execution to finish; instead, it can start running right away.

## setInterval() 
The ```setInterval``` method in JavaScript repeats a specified function at each interval of time. It is a technique for animating a canvas at 60 frames per second. It calls another function at specified intervals of time and then returns a unique id of the performed action.

Syntax: 
    
```javascript
setInterval(function, ms);
```

Parameter: There are two parameters in this method :

* function: first parameter to be executed
* ms: indicates the length of the time interval between each execution.

Example:

```javascript
<p id="OPN"> 
  <script> 
    var myVar = setInterval(myTimer, 1200); 
    function myTimer(){( 
      document.getElementById("OPN").innerHTML += "<p><b>Open Replay</b></p>";
    )} 
  </script>
</p>
```
![-](https://blog.openreplay.com/images/whats-the-best-way-to-do-animations-with-js/images/oIMclKn.gif)


Output: After every 1.2 seconds, a new “Open Replay” message will be displayed.

As the `setInterval()` method executes the function infinitely, there is a method called `clearInterval()`   to stop the execution of the `setInterval()`.

Syntax: 

```javascript
window.clearInterval(value);
```

Parameter: 

* value: The function to be stopped

Example: In this example, we will first execute a `setInterval()` function and then stop its execution by using the `clearInterval()` function.


```javascript
<p id="OPN">
  <button onclick="clearInterval(myVar)"> Stop Execution </button>
  <script>
    var myVar = setInterval(myTimer, 1200); function myTimer()
    {(document.getElementById("OPN").innerHTML += "<p>Open Replay</p>")}{" "}
  </script>
</p>
```
![-](https://blog.openreplay.com/images/whats-the-best-way-to-do-animations-with-js/images/hn20J1y.gif)

Output: The 'Open Replay' message will render on the screen until the user presses the 'Stop Execution' button.


If you run many animations simultaneously, using `setInterval()`  will make debugging difficult. The fact that `setInterval()` will play the animation every 'n' milliseconds, regardless of how long it takes the function to run, is another issue. To put it another way, `setInterval()` may queue too many function executions if the function takes too long to perform.

## setTimeout()
This method executes a function after waiting a specified number of milliseconds. This method executes the code only once.


Syntax:

```javascript
window.setTimeout(function, milliseconds);
```

Parameter: There are two parameters in this method:

* function: first parameter to be executed
* milliseconds: the number of milliseconds before the execution takes place.

Example: 

```javascript
<button onclick="val = setTimeout(opn, 1500);">
  Press me
  <script>
    function opn()
    {alert("Welcome 2023")}{" "}
  </script>
</button>
```
![-](https://blog.openreplay.com/images/whats-the-best-way-to-do-animations-with-js/images/Ji4pCVT.gif)


Output: As soon as the user presses the 'Press Me' button, then after a pause of 1.5 seconds the message alert box 'Welcome 2023' will pop up.

The execution of the `setTimeout()` function is stopped by using a method called as `clearTimeout()`.

Syntax: 

```javascript
window.clearTimeout(value);
```

Parameter:

* value: The function to be stopped.

The `clearTimeout()` method is only used if the function has not been executed. Let us see an example below.

Example: We will use a `setTimeout()` function and stop its execution by using `clearTimeout()` function before the execution of the `setTimeout()`.


```javascript
<p>
  Press Stop Button before the Alert pops up
  <button onclick="val = setTimeout(opn, 2500);">
    Press me
    <button onclick="clearTimeout(val);">
      Stop Execution
      <script>
        function opn()
        {alert("Welcome 2023")}
      </script>
    </button>
  </button>
</p>
```
![-](https://blog.openreplay.com/images/whats-the-best-way-to-do-animations-with-js/images/DiAJ4va.gif)

Output: If we click the STOP button before the alert is shown, the execution of the alert is stopped.

The drawback of using `setTimeout()` is that it does not wait for the timeout period to expire before allowing the remaining JavaScript code to run. In the majority of cases when the function will take a bit longer to perform, this will produce erroneous results.

Traditionally, you could have powered your animation loop using a function like `setInterval` or `setTimeOut`. These two functions have a straightforward issue. They are unaware of everything happening on the rest of the page apart from the animation. This makes them incredibly ineffective at powering animations since they frequently require a repaint or update that your browser isn't prepared to perform. 

`setTimeout` or `setInterval` don't consider any other browser activity. The animation may have scrolled off the page, eliminating the need for a second update request, or the page may be hidden behind a tab, using up needless CPU resources. Secondly, rather than updating the screen whenever the computer can, `setTimeout` only does so when it wants to. That means your poor browser must balance redrawing the animation with redrawing the entire screen. If your animation frame rate is out of sync with the redrawing of your screen, it may consume extra processing power. This results in increased CPU consumption or a depleted battery on your mobile device. These efficiency issues are solved using the `requestAnimationFrame`.






<h2>Session Replay for Developers</h2> 
<p><em>
Uncover frustrations, understand bugs and fix slowdowns like never before with <strong><a href="https://github.com/openreplay/openreplay" target="_blank">OpenReplay</a></strong> — an open-source session replay suite for developers. It can be <strong>self-hosted</strong> in minutes, giving you complete control over your customer data
</em></p>
<img alt="OpenReplay" width="768" height="400" src="https://blog.openreplay.com/assets/overview_Z17Qdyg.png" class="astro-UXNKDZ4E" loading="lazy" decoding="async">
<em>Happy debugging! <a href="https://openreplay.com" target="_blank">Try using OpenReplay today.</a></em>






## requestAnimationFrame()

The `requestAnimationFrame` function was developed by [Mozilla](https://www.mozilla.org/en-US/firefox/) (the company behind [Firefox](https://www.mozilla.org/en-US/firefox/browsers/mobile/android/)) and eventually adopted and refined by the [WebKit](https://webkit.org/) team. It offers a [native API](https://en.wikipedia.org/wiki/Windows_Native_API) for displaying animations of any kind in the browser, whether they are made with [DOM components](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction), [CSS](https://), [WebGL](https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API), or another technology.

Here’s how you use it:

```javascript
function draw() {
  requestAnimationFrame(draw);
} // Code for drawing goes here
draw();
```
   
It is identical to the version with `setTimeout`, except `requestAnimationFrame` is used in its place. You can optionally supply an argument to the function that is being called, such as the element that is currently being animated, like in: 

```javascript
element, requestAnimationFrame;
```

However, you might have observed that you don't mention an interval rate. How frequently is the draw function used then? It all depends on the frame rate of your browser and computer, but generally speaking, it's 60 frames per second (fps). The main distinction is that, instead of specifying an interval, you are asking the browser to render your animation when a suitable chance arises. Additionally, it has been suggested that depending on the load, element visibility (being scrolled out of view), and battery level, browsers may decide to improve the performance of the `requestAnimationFrame`.

The `requestAnimationFrame's` ability to compile all of your animations into a single browser repaint is another benefit. By doing this, CPU cycles are saved, and your gadget has a longer, happier life. Therefore, all of your animations should become silky smooth, synchronized with your [GPU](https://en.wikipedia.org/wiki/Graphics_processing_unit), and consume far less CPU if you utilize `requestAnimationFrame`. Additionally, if you switch to a new tab, the browser will slow the animation down so it won't take over your computer while you're using it.

Syntax: 
    
```javascript
requestAnimationFrame();
```
            

`RequestAnimationFrame` tells the browser to run the animation and ask for an updated animation before the next repaint. It executes a callback after the browser paints the screen, as opposed to `setTimeout`, which does it after the specified time delay. Since `requestAnimationFrame` will wait until the browser is prepared to paint rather than execute the function even if the browser is not, this alone makes it more efficient than `setInterval`.

The `requestAnimationFrame` method in JavaScript simply takes one argument: a function to run. The operation of the function you gave to `requestAnimationFrame` will start when the browser is ready to redraw the screen. The CPU power of the machine running the code and the refresh rate of the display the browser is on will affect when this function executes.

Example :

```html
<h1>
  <b>requestAnimationFrame Demo</b>
  <h1>
    <button class="startanimation">Start</button>
    <button class="stopanimation">Stop</button>
    <div class="circle"></div>
  </h1>
</h1>
```

```css
.circle {
  border-radius: 100 %;
  width: 200 px;
  height: 200 px;
  background-color: purple;
  align-items: center;
  justify-content: center;
  font-family: Arial;
  position: relative;
}
 ```


```javascript
function easeInCubic(t) {
  return t ** 3;
}
const circle = document.querySelector(".circle");
const startButton = document.querySelector(".startanimation");
const stopButton = document.querySelector(".stopanimation");
let animationId = null;

function animate(element, duration) {
  window.cancelAnimationFrame(animationId);
  let start = null;

  function step(timestamp) {
    if (!start) {
      start = timestamp;
    }
    const progress = timestamp-start;
    const translation = 1000 * easeInCubic(progress / duration);
    console.log(progress, translation);
    //element.style.transform = `translateX(${translation}px)`;
    element.style.left = translation + "px";
    if (progress < duration) {
      animationId = window.requestAnimationFrame(step);
    }
  }
  animationId = window.requestAnimationFrame(step);
}
startButton.addEventListener("click", () => animate(circle, 2000));
stopButton.addEventListener("click", () => {
  window.cancelAnimationFrame(animationId);
});
```

![-](https://blog.openreplay.com/images/whats-the-best-way-to-do-animations-with-js/images/mvLDeAJ.gif)

Output: 

A purple color ball will go from left to right on pressing the 'Start' button for a duration of 2000ms(2 seconds). After the user clicks on the 'Stop' button, the ball will stop immediately.

Just before the animation runs, we set the startime variable to the current time using `requestAnimationFrame's` timestamp. Its value is automatically passed in as the first parameter of the callback function of `requestAnimationFrame` that contains a highly accurate representation of the current time in milliseconds (accurate to 5 microseconds). This informs us when the animation started running.

Inside the animation `function step(timestamp)`, we capture the current time of the current "frame" using the variable `timestamp`. We use the difference between that and the animation start time to figure out at what "point" along the animation we're currently at.

We stop the ball using `window.cancelAnimationFrame(animationId);` as explained below in detail.

### Cancelling requestAnimationFrame()

Syntax: 

```javascript
window.cancelAnimationFrame(animationId);
```
    
Similar to `setInterval`/`setTimeout`, one can cancel a `requestAnimationFrame` call. `RequestAnimationFrame` when called returns a non-0 integer that can be captured inside a variable and passed into its counterpart `cancelAnimationFrame()` to stop it from being invoked again.

Within the function `animate(element,duration)`,`window.cancelrequestanimationframe()`; is called. So the animation will stop either when the duration of 2000ms is reached or when the user presses the 'STOP' button whichever is done first. The above code logs the `timestamp` parameter value of `requestAnimationFrame` for 2 seconds(2000ms), using `cancelAnimationFrame` to stop the former.

## Advantage of requestAnimationFrame

The following are the advantages of using `requestAnimationFrame` :

### Animations Only Run When Visible

When you use requestAnimationFrame, your animations only play when the user can see the tab (or window). This results in decreased use of the CPU, GPU, and memory.`RequestAnimationFrame` uses CPU efficiency by avoiding rendering while a tab or window is hidden. `RequestAnimationFrame` will cease executing animation operations if the focused browser tab changes to avoid wasting resources.

### Browser Optimization 

When you use `requestAnimationFrame`, the browser enhances your animations to make them smoother by using fewer resources. It groups several animations into a single reflow and repaint cycle and does away with the potential of pointless draws.

### Battery Friendly
 
By reducing the number of "tasks" a device needs to perform to produce your animations, the optimizations outlined in the previous two paragraphs all contribute to battery power conservation. This is crucial for mobile devices since batteries normally last just a short time.
 
Since most of the libraries we'll be working with utilize it internally, `requestAnimationFrame` is a fairly high-performance approach to animating. Similar to recursion, `requestAnimationFrame` performs the logic before drawing the next frame in a series and then calls itself once more to continue.

## Drawbacks of requestAnimationFrame

Despite its advantages over other methods of animation, `requestAnimationFrame` has few drawbacks.


### Browser Support

Since this is a new API, it is only now accessible in browsers through a vendor prefix, such as `webkitRequestAnimationFrame` in Chrome, Safari, and Firefox. Overall, browser support is decent; however, Microsoft only supports `msRequestAnimationFrame` in IE10 and later.

See the ['Can I Use'](https://caniuse.com/requestanimationframe) tables to check the browser support for `requestAnimationFrame`. The only problems are iOS 5-, IE 9- and Android. But these can be fixed using the following:

### Polyfill

A polyill has been created by Paul Irish ([Google](https://www.google.com/)), Eric Möller ([Opera](https://www.opera.com/?utm_campaign=%2307%20-%20IN%20-%20Search%20-%20EN%20-%20Branded%20-%202017&gclid=CjwKCAiAzp6eBhByEiwA_gGq5LYRx3gjIkny8NgWpO-mvAfPXHOqht08GfcvQZ9qyn0VcFvcIN9wpBoCxJ4QAvD_BwE)) and Tino Zijdel ([Tweakers.net](https://tweakers.net/)).


Using this, one can use requestAnimationFrame in literally any browser.
```javascript
(function () {
  var lastTime = 0;
  var vendors = ["ms", "moz", "webkit", "o"];
  for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
    window.requestAnimationFrame = window[vendors[x] + "RequestAnimationFrame"];
    window.cancelAnimationFrame =
      window[vendors[x] + "CancelAnimationFrame"] ||
      window[vendors[x] + "CancelRequestAnimationFrame"];
  }
  if (!window.requestAnimationFrame)
    window.requestAnimationFrame = function (callback, element) {
      var currTime = new Date().getTime();
      var timeToCall = Math.max(0, 16-(currTime-lastTime));
      var id = window.setTimeout(function () {
        callback(currTime + timeToCall);
      }, timeToCall);
      lastTime = currTime + timeToCall;
      return id;
    };
  if (!window.cancelAnimationFrame)
    window.cancelAnimationFrame = function (id) {
      clearTimeout(id);
    };
})();
```
You can drop this in your code and can use `requestAnimationFrame` as desired.

### Variation in Animation Speed

`RequestAnimationFrame` allows us to generate animations, but not all users will experience them at the same speed. The reason is that the timing of the browser's decision to do a repaint has a significant impact on how quickly `requestAnimationFrame` is called. The device's screen refresh rate is a significant element in whether a repaint occurs, among many others.

An animation's running speed varies wildly depending on whether one is viewing the animation on a 60Hz screen (screen tries to redraw 60 times per second) or on a 120Hz screen (screen tries to redraw 120 times per second). This variation isn't desirable, especially when we use `requestAnimationFrame` to power our game loops and other visually-intense animations whose speed we want to keep consistent.

Let's take a closer look at why `requestAnimationFrame` performs differently depending on the user. Unquestionably an important reason is the refresh rate of the screen. While many devices only have a 60Hz refresh rate, more of us are using 75Hz, 90Hz, 120Hz, 240Hz, or even greater refresh rates on devices like higher quality laptops, desktops with gaming displays, newer mobile phones, etc.

The speed at which an animation loop driven by `requestAnimationFrame` operates depends on several factors in addition to the refresh rates. The repaint is given less attention since the browser is too busy with something more important. The browser is shrunk, or the attention is lost on the browser tab. The gadget slows down when optimizing for battery and CPU. High refresh rates are not supported by the browser(eg, Safari). 

We must consider these and devise a method to guarantee that everyone views our visual updates and animations at the same rate. Animations that play at the same speed for every user can be made.

## Setting Frame Rate to a Consistent Value

It's crucial to keep the frames per second limit under control, especially when creating games with animated elements that must not go above a certain threshold. The `requestAnimationFrame()` method is not a timer or a loop; instead, it is used to simply redraw the screen.

`RequestAnimationFrame` is a good choice for frame rate management since each time a function call is made, the screen or frame is repainted in accordance with the developer's update code. 

There are two ways to set the frame rate to a consistent value. They are as below :


### Using `setTimeout()` method

The `setTimeout()` method is used to regulate frame rate, while the `requestAnimationFrame()` function is used to update the screen at the defined intervals.

The following code demonstrates how to manage the frame rate using `setTimeout()`. To keep the screen refreshing at the desired frame rate, `requestAnimationFrame()` is sent to `setTimeout()` as a function.

```javascript
var frameCount = 0;
var $results = $("#results");
var fps, fpsInterval, startTime, now, then, elapsed;
startAnimating(5);

function startAnimating(fps) {
  fpsInterval = 1000 / fps;
  then = Date.now();
  startTime = then;
  console.log(startTime);
  animate();
}

function animate() {
  setTimeout(function () {
    // requestAnimationFrame() is called
    // with animate() callback
    // to update content at specified fps
    requestAnimationFrame(animate);
    // ... Code for Animating the Objects ...
    now = Date.now();
    var sinceStart = now-startTime;
    var currentFps =
      Math.round((1000 / (sinceStart / ++frameCount)) * 100) / 100;
    $results.text(
      "Elapsed time= " +
        Math.round((sinceStart / 1000) * 100) / 100 +
        " secs @ " +
        currentFps +
        " fps."
    );
  }, fpsInterval);
}
```
Output: 

After 5.31 seconds have elapsed, FPS is 4.9
![-](https://blog.openreplay.com/images/whats-the-best-way-to-do-animations-with-js/images/1cYId7d.png)


After 18.34 seconds have elapsed, FPS is 4.91
![-](https://blog.openreplay.com/images/whats-the-best-way-to-do-animations-with-js/images/zVyeDT6.png)


The `setTimeout()` method is simply called in the code above at the fps-specified interval rate. `RequestAnimationFrame()` is called each time `setTimeout()` is used, which causes the screen to be updated or repainted. All of this happens at the developer-specified frame rate.

### Better Approach 

We force our animation loop to run at a constant speed by fixing the frame rate. Fixing the frame rate is one method for maintaining consistency. We don't do this by depending on `requestAnimationFrame's` execution speed. We instead rely on the intervals between frame updates (aka the frame interval). Let's imagine we want to animate at 60 frames per second. This implies that every 16.67 milliseconds (1 second / 60 frames), our code that updates the visuals must run.

To further highlight the statistics, let's look at how often our code must execute to animate at 24 frames per second: 

1 second / 24 frames = 41.667 milliseconds.

It doesn't matter how fast or slow `requestAnimationFrame` is operating while we are running our animation-related code repeatedly at a predetermined time interval. The only factor that counts is the amount of time that has passed since the last call to our animation code.

The code for doing the above is as follows:

```javascript
// set the expected frame rate
let frames_per_sec = 60;
let interval = Math.floor(1000 / frames_per_sec);
let startTime = performance.now();
let previousTime = startTime;
let currentTime = 0;
let deltaTime = 0;

function animationLoop(timestamp) {
  currentTime = timestamp;
  deltaTime = currentTime-previousTime;
  if (deltaTime > interval) {
    previousTime = currentTime-(deltaTime % interval);
    // add your visual updates-related code
  }
  requestAnimationFrame(animationLoop);
}
requestAnimationFrame(animationLoop);
```
        
                    
Output:

The above code will play the animation at 60ps as fixed. We fix the frame rate by using `requestAnimationFrame` as a timing loop and checking the amount of time elapsed (delta time) between each requestAnimationFrame call.


## Conclusion

Only when you need to execute quick animations and make sure that browsers will render them smoothly should you choose `requestAnimationFrame` over CSS animations or `setInterval`/ `setTimeout`. Using `requestAnimationFrame` might be advantageous for animations like leap, stop, pause, and return.

The `requestAnimationFrame` method only draws animation that the user would see (it doesn't use any CPU resources if you switch tabs, minimize, etc.). There would be no unnecessary frame draws since the browser would only draw frames when it was ready to do so and there would be no ready frames that were waiting to be drawn. So you may choose `requestAnimationFrame` with confidence since smoothness is guaranteed. If you wish to make a simple animation, you can opt for CSS animations or use `setInterval` and `setTimeout` instead.

[![newsletter](https://blog.openreplay.com/newsletter_Z1P0UIP.png)](https://newsletter.openreplay.com/)