Skip to content Skip to sidebar Skip to footer

Optimizing Javascript For Multiple Browser Display At High Fps

I have an FFT using canvas that plots a high speed display. I want to optimize the code to have 16 browser windows showing at the same time at 60 fps or close to it. Right now on m

Solution 1:

60 fps animation on multiple windows

99.99% of the time, requestAnimationFrameis the way to do visual animations. It's a great tool, synced with the screen refresh rate, with great timing precision, and battery friendly.

This last advantage is your problem : To save power, browsers do allow the screen synchronization only for the currently focused window at 60fps. All other windows are delayed, on a lower frame-rate. Since you want to have multiple windows, you'll be able to get only one focused, and thus only one refreshing at 60fps, all others will be slowed down to about 5fps.

How to circumvent this ?

The WebAudioAPI does have its own low-level and high-precision clock system. By "low-level", I mean that this clock system is not tied to the main js-thread*. On some implementations (chrome) all the WebAudioAPI even runs on a parallel thread. And more importantly to our case, this clock system is not only tied to focused window. This does mean that we can run code, in a background window, at 60fps.

Here is a simple implementation of an timing loop based on the WebAudioAPI clock.

(*Note that while the clock is not tied to the main js thread, the event handler is).

/*
    An alternative timing loop, based on AudioContext's clock

    @arg callback : a callback function 
        with the audioContext's currentTime passed as unique argument
    @arg frequency : float in ms;
    @returns : a stop function
    
*/functionaudioTimerLoop(callback, frequency) {

  var freq = frequency / 1000;      // AudioContext time parameters are in secondsvar aCtx = new AudioContext();
  // Chrome needs our oscillator node to be attached to the destination// So we create a silent Gain Nodevar silence = aCtx.createGain();
  silence.gain.value = 0;
  silence.connect(aCtx.destination);

  onOSCend();

  var stopped = false;       // A flag to know when we'll stop the loopfunctiononOSCend() {
    var osc = aCtx.createOscillator();
    osc.onended = onOSCend; // so we can loop
    osc.connect(silence);
    osc.start(0); // start it now
    osc.stop(aCtx.currentTime + freq); // stop it next frame
    callback(aCtx.currentTime); // one frame is doneif (stopped) {  // user broke the loop
      osc.onended = function() {
        aCtx.close(); // clear the audioContextreturn;
      };
    }
  };
  // return a function to stop our loopreturnfunction() {
    stopped = true;
  };
}

And call it like that :

var stop_anim = audioTimerLoop(yourCallback, 60); // runs 'yourCallback' every 60ms

And to stop it :

stop_anim();

All right, Now we are able to run smooth animation even on blurred windows.

But I want to run it on 16 windows !

Unfortunately, browsers are tied to hardware limitations when creating AudioContext. (e.g. on my computer, I can not have more than 6 contexts running at the same time.)

Here the solution is to run all the code on a single, master window.

From this master window, you'll first

  • Open all the other windows, so that you can access their content,
  • Grab the contexts of your canvas elements,
  • draw on these contexts

This way, you've got a single update thread, on the main window, and all other windows only have to render.


Live Example

(Be sure to allow popups and to disable your ad-blocker though).

Post a Comment for "Optimizing Javascript For Multiple Browser Display At High Fps"