0

I am developing a game using HTML5 Canvas and JavaScript. Initial fps is decent but as the game continues the fps decreases. The initial fps is around 45 fps but it reduces to 5 fps.

Following is my gameloop

var last_draw = Date.now(); //To track when last time GameDraw was called last time
var fps;
function gameloop()
{
    var elapsed = Date.now() - last_draw;
    last_draw = Date.now()
    fps = 1000/elapsed;
    context.clearRect(0,0,canvas.height,canvas.width);// This function clears the canvas.
    GameUpdate();// This function updates property of all game elements.
    GameDraw(); //This function draws all visible game elements in the canvas.
    window.requestAnimationFrame(gameloop); //Requests next frame
}

window.requestAnimationFrame(gameloop); 

It have tested this in following browsers:

  1. Mozilla Firefox 32.0.3
  2. Google Chrome 38.0.2125.101 m

My questions are:

  1. Why rAF is calling it less frequently as the game continues?
  2. Is it due to Memory leak?
  3. Is it because time taken by GameDraw and GameUpdate is very high?
  4. Is time to execute Gamedraw function is different from time taken to actually draw elements in canvas. Gamedraw calls draw function of each game element.
Shomz
  • 37,421
  • 4
  • 57
  • 85
  • 3
    Your looping code looks fine. There is no way we can help you find the exact problem without more information. Chrome developer tools have excellent tools to check for memory leaks or to profile (measure execution speed) of different functions. I recommend the free course https://www.codeschool.com/courses/discover-devtools to learn how to use these tools. – Iftah Oct 12 '14 at 14:11
  • Thank you sir for your reply. You are right I should first learn chrome devtools in order to eliminate my problem. – Anubhav Choudhary Oct 12 '14 at 14:48
  • https://stackoverflow.com/questions/11150779/redrawing-html5-canvas-incredibly-slow – Sérgio S. Filho Jan 25 '23 at 03:01

1 Answers1

1

You'll find a lot of online tutorials about optimizing canvas performance. It's not about using this-or-that function, it's about the amount of processing that happens between each two frames.

Since your question(s) can't have one solid answer, I'll briefly address each of the sub-questions:

Why rAF is calling it less frequently as the game continues?

Like you guessed in the next question - something is leaking: it could be anything from, say, adding more textures, event listeners, DOM objects, etc. in every cycle... to simply having too many JS objects piling up because they remain referenced so the Garbage Collector can't get rid of them. But the bottom line is that you need to discover what is changing/incresing between each two frames.

Is it due to Memory leak?

Very probable, and yet so easy to test. In Chrome, Shift+Escape opens the task manager where you can see memory, cpu, etc. usage for each open tab. Monitor that.

Is it because time taken by GameDraw and GameUpdate is very high?

Most definitely! This could also be causing memory leaks. Learn to do CPU and canvas profiling, it will help you a lot. I believe canvas profiling in Chrome is still an experimental feature, so you'd need to enable it first from the config flags. These two functions are where 99% of the lag comes from, investigate what's going on there.

Is time to execute Gamedraw function is different from time taken to actually draw elements in canvas. Gamedraw calls draw function of each game element.

That shouldn't matter because both of them are blocking codes, meaning that one will only happen after another. The time to render a frame is roughly the sum of the two. Again, proper canvas rendering optimization can do wonders here.

Shomz
  • 37,421
  • 4
  • 57
  • 85
  • Sir, i have recorded timeline of my game using chrome devtools. It seems like time to run script, render and paint is less than 16ms but there is gray bar for "others" as mentioned in chrome devtools is taking more time. Can you explain what this gray bar represents? following is link to snapshot of timeline - [Timeline Snapshot](https://drive.google.com/file/d/0B34WuAFidsDNeHJ3YU1POVVUSzA/view?usp=sharing) – Anubhav Choudhary Oct 13 '14 at 07:40
  • It could be a lot of things. Try expanding your devtools to the fullscreen, then use mouse to select a part of the timeline. A list with all the event for that period will show up below. Isolate those that take the most time and see if there's something you can do to optimize them. – Shomz Oct 13 '14 at 08:03
  • In chrome browser I used task manager to monitor the memory and CPU and according to observation memory was continuously increasing with time and CPU was 25. Now it is sure that objects are being created and it is not garbage collected. So show me directions to tackle this situation. I would also like to tell that in my game most of the time I have created objects using new operator and stored its reference in an array. To clear that object I just used splice function in array to clear its reference. Is it sufficient to enable that object for garbage collection? – Anubhav Choudhary Oct 13 '14 at 18:31
  • If it locks up at 25 percent, it tells me that you have a quad core CPU and one core is constantly fully used (JS doesn't support multi-threading, not going into the whole web workers story here). That might be just okay if you're using software rendering, so basically the GPU is idle the whole time. Memory usage increase tells us that something is constantly piling up. About the last question, I can't tell you a definite yes or no without seeing what it does, but it's quite possible that those objects (or their properties) have other references. Add a button to clear the whole array and test. – Shomz Oct 13 '14 at 21:40
  • If the array cleanup frees the memory, then try actually deleting objects after splicing their array. Also, I assumed you're not using global variables, but if you are, fix that first. This is useful: https://developer.chrome.com/devtools/docs/javascript-memory-profiling – Shomz Oct 13 '14 at 21:44