views:

346

answers:

3

How can I tell if the canvas's slow performance is caused by the drawing itself, or the underlying logic that calculates what should be drawn and where?

The second part of my question is: how to calculate canvas fps? Here's how I did it, seems logical to me, but I can be absolutely wrong too. Is this the right way to do it?

var fps = 0;  
setInterval(draw, 1000/30);  
setInterval(checkFps, 1000);  

function draw() {  
   //...  
   fps++;  
}  

function checkFps() {  
   $("#fps").html(fps);  
   fps = 0;  
}

Edit: I replaced the above with the following, according to Nathan's comments:

var lastTimeStamp = new Date().getTime();  
function draw() {  
    //...  
    var now = new Date().getTime();  
    $("#fps").html(Math.floor(1000/(now - lastTimeStamp)));  
    lastTimeStamp = now;  
}

So how's this one? You could also calculate only the difference in ms since the last update, performance differences can be seen that way too. By the way, I also did a side-by-side comparison of the two, and they usually moved pretty much together (a difference of 2 at most), however, the latter one had bigger spikes, when performance was extraordinarily low.

+1  A: 

Webkit and Firebug both provide profiling tools to see where CPU cycles are being spent in your javascript code. I'd recommend starting there.

For the FPS calculation, I don't think your code is going to work, but I don't have any good recommendation :(

Reason being: Most (all?) browsers use a dedicated thread for running javascript and a different thread for running UI updates. If the Javascript thread is busy, the UI thread won't be triggered.

So, you can run some javascript looping code that'll "update" the UI 1000 times in succession (for instance, setting the color of some text) - but unless you add a setTimeout to allow the UI thread to paint the change, you won't see any changes until the 1000 iterations are finished.

That said, I don't know if you can assertively increment your fps counter at the end of the draw() routine. Sure, your javascript function has finished, but did the browser actually draw?

desau
A: 

Your FPS code is definitely wrong

setInterval(checkFps, 1000);  

No-one assures this function will be called exactly every second (it could be more than 1000ms, or less - but probably more), so

function checkFps() {  
   $("#fps").html(fps);  
   fps = 0;  
}

is wrong (if fps is 32 at that moment it is possible that you have 32 frames in 1.5s (extreme case))

beter is to see what was the real time passes since the last update and calculate the realtimepassed / frames (I'm sure javascript has function to get the time, but I'm not sure if it will be accurate enough = ms or better)

fps is btw not a good name, it contains the number of frames (since last update), not the number of frames per second, so frames would be a better name.

In the same way

setInterval(draw, 1000/30);

is wrong, since you want to achieve a FPS of 30, but since the setInterval is not very accurate (and is probably going to wait longer than you say, you will end up with lower FPS even if the CPU is able to handle the load)

Nathan
A: 

Check if you dont use some innerHTML method to debug your project. This can slow your project in a way you can't imagine, especially if you do some concatenation like this innerHTML += newDebugValues;

Or like desau said, profile your cpu usage with firebug or webkit inner debugger.

762x51mm