May 27, 2013

JavaScript: Throttle requestAnimationFrame to maintain 30fps

One problem with using requestAnimationFrame is that rendering will take place as quickly as the computer can process the per-frame calculations and screen redraw. If you only want to run at 30fps, your computer might be running a lot faster than you want. To work around this problem, simply check the elapsed time before running the next frame update. Check out the example:
var frameLength = 33; // this is ~1/30th of a second, in milliseconds (1000/30)
var lastFrame = 0;

var render = function() {
  if(Date.now() - lastFrame > frameLength) {
    lastFrame = Date.now()

    // run your 30fps code here...
  }
  requestAnimationFrame(render);
};
requestAnimationFrame(render);
You'll notice that I'm using Date.now(), which requires a polyfill for old versions of IE. requestAnimationFrame also requires a polyfill for some browsers. Another solution is to use time-based calculations, but that's not always easy to implement.

1 comment:

  1. You could do something like:

    /**
    * A throttle function
    * http://remysharp.com/2010/07/21/throttling-function-calls/
    */
    function throttle(fn, threshhold, scope) {
    threshhold || (threshhold = MAX_DELAY_MSEC);
    var last,
    deferTimer;
    return function () {
    var context = scope || this;

    var now = +new Date,
    args = arguments;
    if (last && now < last + threshhold) {
    // hold on to it
    clearTimeout(deferTimer);
    deferTimer = setTimeout(function () {
    last = now;
    fn.apply(context, args);
    }, threshhold);
    } else {
    last = now;
    fn.apply(context, args);
    }
    };
    }


    and then

    elem.myEventListener('theEvent',throttle(function(){

    /// execute

    }),MAX_DELAY_MSEC);

    ReplyDelete