Tips for optimizing the "framerate" (setInterval delay) in a JavaScript animation loop

When creating a JavaScript animation, it's common practice to use setInterval (or multiple setTimeouts) to create a loop. But what is the optimal delay to set in these setInterval/setTimeout calls?

In the jQuery API page for the .animate() function, user "fbogner" mentions:

For those interested: Animations are created using a setInterval with a timeout of 13ms. This is quite speedy! Chrome has the fastest possible interval of around 10ms, while other browsers typically sample at 20-30ms.

How did jQuery arrive at this specific number for their animations?


I've started a bounty in hopes that someone familiar with the source code of Chromium or Firefox can offer concrete evidence to support the choice of a particular framerate. It would be interesting to see a compilation of different animations (or frameworks) and their corresponding delays. I believe this could lead to some enlightening research.


Fascinating discovery - I recently examined Google's Pac-Man source code to understand their approach. They implemented an array of various FPS values (90, 45, 30), beginning with the highest one. During each frame, they assess the "slowness" of the frame (how much it surpassed its designated time). If this slowness surpasses 50ms on 20 occasions, the framerate is decreased to the next value in the list (90 -> 45, 45 -> 30). Interestingly, the framerate doesn't return to higher values, likely because the game is relatively short-lived, making the effort not worthwhile.

Furthermore, the setInterval delay is calculated as 1000 / framerate. Notably, they opted for setInterval over repeated setTimeouts.

This dynamic framerate functionality is indeed quite impressive!

Answer №1

It is likely that a significant portion of internet users have monitors with a refresh rate of 60Hz, meaning one frame every 16.66ms. To make the monitor the limiting factor, you would need to produce frames at a rate faster than 16.66ms.

The choice of a value like 13ms can be attributed to two reasons. Firstly, the browser requires some time to repaint the screen (generally at least 1ms). This results in an update frequency of around 15ms, which coincidentally happens to match the standard timer resolution on Windows of 15ms (refer to John Resig's blog post). A well-crafted 15ms animation should look consistent across various browsers and operating systems.

For what it's worth, fbogner is incorrect in stating that non-Chrome browsers fire setInterval every 20-30ms. I conducted a test to measure the firing speed of setInterval and obtained the following results:

  • Chrome - 4ms
  • Firefox 3.5 - 15ms
  • IE6 - 15ms
  • IE8 - 15ms

Answer №2

In order to manage the frame rate of a drawing application, the following pseudo-code can be utilized:

FPS_WANTED = 25 
(just a starting point, subject to change during execution)

TIME_OF_DRAWING = 1000/FPS_WANTED 
(in milliseconds, providing an accurate measurement for frame rate)
(should be adjusted as FPS_WANTED is modified)

UntilUserExitsApplication()
{

  time1 = getTime();
  doAnimation();
  time2 = getTime();
  animationTime = time2-time1;

  if (animationTime > TIME_OF_DRAWING)
  {
     [the desired FPS cannot be achieved]
     Options:
     1. Reduce FPS to test lower frame rates
     2. Maintain current settings for maximum CPU performance
  }
  else
  {
     [the target FPS can be attained - choices include:]
     1. wait(TIME_OF_DRAWING-animationTime) - sustain constant FPS
     2. increase frame rate if preferred
     3. Opt for best CPU utilization without adjustments
  }

}

While variations may exist, this fundamental algorithm is applicable in all animated scenarios.

Answer №3

When it comes to creating looping animations, striking a balance between speed and workload is crucial.

For instance, if you aim to smoothly slide a div across the screen in one second for a visually appealing effect, you'll need to adjust the loop speed accordingly. This ensures that the animation is both noticeable and seamless.

Ultimately, finding the perfect balance may require some trial and error, taking into consideration factors such as workload, time, and browser capabilities. The goal is to create an animation that looks great on any browser.

Answer №4

fbogner's provided number has undergone testing. Web browsers limit the execution of JavaScript activity to ensure usability each time.

If JavaScript were able to run every 5 milliseconds, the browser runtime would have less CPU time available for rendering updates or responding to user input (such as clicks) because JavaScript execution slows down the browser.

I believe that Chrome developers permit shorter intervals for running JavaScript compared to other browsers due to their V8 Javascript Engine, which compiles JavaScript code for faster performance and reduces the amount of time the browser is blocked by interpreted code.

However, the engine's speed alone is not sufficient to allow for shorter intervals; the developers have likely conducted tests to determine the optimal shortest interval that allows for quick execution without significantly slowing down the browser.

Answer №5

It's interesting to consider the interval time in jQuery and how 13ms equates to 80fps, showing just how fast it truly is. Typically, the "standard" frames per second used in movies and other media is 25fps, which is adequate to not cause any noticeable flickering for the human eye. With 25fps translating to 40ms, we can conclude that anything below 40ms should be sufficient for smooth animations.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How can I effectively display a blank menu item for the SelectField component in Material-UI within a React application?

I am using the select-field component from the material-ui framework version 0.15.4 with React version 15.4.0. I am attempting to add a blank menu-item to the select-field in order to allow for deselecting a value in the dropdown field when clicked. Howeve ...

Exploring the power of React Leaflet and the exciting possibilities of React Leaflet

I'm currently in the process of implementing the draw functions on a leaflet map. I started off by creating a new app with just react-leaflet installed. I used npx create-react-app and installed the following packages: npm install react react-dom lea ...

Can you provide instructions on how to use JavaScript to click and hold a button for a specific duration?

Is it possible to use jQuery to create a button that, when guest button number 1 is clicked, will automatically click and hold down button number 2 for about 3 seconds? I have tried using the mousedown() and click(), but they only register a click, not a ...

Creating HTML code using Django and JavaScript

Greetings world! I am relatively new to Python and JavaScript, so my coding techniques might seem unconventional to seasoned developers. However, I am eager to learn and improve. I have an HTML page where Django generates some code for a calendar: Here&a ...

jQuery ajax errors are slipping through the cracks and not being properly addressed

I'm struggling with the jQuery ajax success handler. I've noticed that any JavaScript errors that occur within the success handler are not being reported (no errors show up in the Firefox error console). This lack of error notifications is making ...

Guide to authenticating Cashfree gateway's webhook signature using JavaScript

I have integrated the Cashfree payments gateway successfully. However, I am unsure how to verify the signature of webhooks. https://i.stack.imgur.com/TxdTx.png This is their recommended approach. Could someone guide me on writing JavaScript code for this ...

Directive unable to recognize ng-pattern functionality

I am attempting to encapsulate an <input> within a directive in order to manage date validation, conversion from string to Date object, and keep the Date version in the original scope. The functionality seems to be working as intended. However, the n ...

The pageSize in React's Material Table does not reflect dynamic updates

Currently, I am attempting to implement pagination for material table data using TablePagination. One issue I am facing is that the pageSize property, initially defined as a state variable, does not update when the selected pageSizeOptions change. Despite ...

Refresh Subview in Subview with MVC AJAX Update

My MVC 5 web application features a Razor View named CreateProposal, which takes in a ViewModel called ProposalViewModel. Within this view, there is a reference to a Partial View called _Proposal, also accepting the same ViewModel. CreateProposal View @m ...

Creating a new object store in IndexedDB on Windows 8

Encountering issues with creating an object store in IndexedDb while trying to build a Metro app using Javascript. The code snippet below shows my attempt within the 'dbReq.onsuccess' function that is supposed to create the object store upon succ ...

Image displayed in tooltip when hovering over

I have been experimenting with displaying an image in a tooltip when hovering over it. I came across a fantastic solution that suits my needs: Codepen CSS: @import "compass"; * { box-sizing: border-box; } .tooltip { position: relative; border-bo ...

Guide on extracting JSON data from jQuery containing an array in C#

Looking for a way to extract array data from JSON in C#? Here is an example of the AJAX code: $.ajax({ type: "GET", url: "/Weather/GetWeather", data: { "a": ["1,","2&"], "b" : 4 }, success: onSc ...

How can we extract word array in Python that works like CryptoJS.enc.Hex.parse(hash)?

Is there a method in Python to convert a hash into a word array similar to how it's done in JavaScript? In JavaScript using CryptoJS, you can achieve this by using: CryptoJS.enc.Hex.parse(hash), which will provide the word array. I've searched ...

Rearrange the layout by dragging and dropping images to switch their places

I've been working on implementing a photo uploader that requires the order of photos to be maintained. In order to achieve this, I have attempted to incorporate a drag and drop feature to swap their positions. However, I am encountering an issue where ...

Can one customize the background color of a segment in a radar chart using Chart.js?

Could I customize the color of the sectors in my radar chart to resemble this specific image? https://i.stack.imgur.com/U8RAb.png Is it feasible to achieve this using Chart.js? Alternatively, are there other chart libraries that have this capability? It ...

What's the best way to send a message back to AJAX along with a code from PHP?

Hi everyone, I'm facing an issue with my AJAX function that calls a PHP URL using the html data type. Unfortunately, I can't use other datatypes for my AJAX requests because of server restrictions. I am trying to display a message and handle dif ...

smoothly hide the dropdown menu when a link is clicked with a transition effect

I am struggling with two bugs in my dropdown menu that I can't seem to fix. The navigation links on my homepage take users to different sections of the page instantly when clicked. However, the issue arises when the dropdown menu does not close after ...

Running NodeJS scripts with ElectronJS is not possible

Goal I'm facing a challenge with executing my separate scripts located in the project/api folder. Let's take test.js as an example, where I am exporting it using module.exports. When I run my electron window and create a JavaScript file with a f ...

The build process encountered an error due to the absence of ESLint configuration after the import

Having recently worked on a Vue project created using Vue CLI, I found that eslint was also included in the project. Although I haven't utilized eslint much up to this point, I understand that it is beneficial for catching stylistic errors, semantic e ...

Updating ngModel value dynamically from controller

I have been trying to update the value of an ngModel variable from my controller, but it doesn't seem to be reflecting in the views. Despite looking at other solutions on SO, nothing has worked for me so far. I am looking for a solution that doesn&apo ...