0
\$\begingroup\$

we're developing a HTML5/Javascript jump and run game and therefore we have developed our own gameframework. It consists of following most important structures:

  • Stage/Scene/Layer: divs
  • ObjectEntites/Rectangle/Sprite: canvas

In the gameloop things get moved by calculating an offset value: e.g. if we place a coin and this coin moves through the screen, it gets a new offset in each gameloop-call. The dirty area of the coin is cleared in the canvas and the coin is repainted. We pay attention that we just draw at int-values (no floating point).

Unfortunately we have some performance issues now and can't figure out why our macbook pro's are running hot while playing the game.

Are the drawing operations so crucial? We have layered Canvas, so just moving stuff gets repainted and even not the whole canvas but just dirty-areas get cleared.

IStat shows following values while playing the game: Memory module A1 and Heatsink B get up to 60° and the rpm-Value of the Fans increases up to 3000-4000. In firefox we see these values:

firefox

And chrome shows us this, where we also see how cpu increases: chrome

Do you have any idea how to check performance of our game, how to find bottlenecks or general tips? We have searched for canvas performance, used firebug profiler... We'd be grateful for any advice!

\$\endgroup\$
4
  • 1
    \$\begingroup\$ What do you mean by performance issues? What is your update rate? \$\endgroup\$ Commented Sep 11, 2013 at 13:56
  • \$\begingroup\$ our average-fps is about 60. By performance issues we mean after playing several minutes, out macbooks get loud. We assume the problem lies in the drawImage() method, which is called every gameloop, cause the entities move by a tiny offset. If we uncomment the drawImage(), this does not happen, so we're looking for alternatives and have tried out offscreen-canvas, but doesn't seem to minimize the lack... maybe we have to find some alternatives here!? \$\endgroup\$ Commented Sep 11, 2013 at 16:15
  • \$\begingroup\$ Why don't you use Activity Monitor or top instead and take a look at CPU load? a full thread of load usually heats my rMBP up a little but not enough to speed up the fans. Because of that, I am already inclined to agree something may not be right. Anyway, sounds like you care too much about performance not to go WebGL or native with this, unless you need this working on mobile or something (in which case, it's probably already too sluggish if it heats up the Mac) \$\endgroup\$
    – Steven Lu
    Commented Sep 12, 2013 at 8:11
  • \$\begingroup\$ The requestAnimationFrame() method might help a bit: developer.mozilla.org/en-US/docs/Web/API/… \$\endgroup\$ Commented Dec 19, 2013 at 19:15

4 Answers 4

4
\$\begingroup\$

I recently watched a Google I/O 2012 video (http://www.youtube.com/watch?v=Prkyd5n0P7k) which talks about using an off-DOM canvas to perform your rendering, then "blitting" that canvas to an on-DOM canvas for final presentation. The speaker indicates their game saw a 30X performance increase simply by using an off-DOM canvas. YMMV, but maybe this will help you out.

\$\endgroup\$
1
2
\$\begingroup\$

It doesn't seem that you have a real issue.

The exact amount depends on the browser, but pretty much all over the line canvas is a compute expensive tool relative to the number of pixel you push through.

Your CPU gets hot, that is to be expected if you do anything moderately complex with a canvas.

I'm not saying that there necessarily isn't something smart you can do to decrease the processing required, but from the very moderate amount of information you give about your game I don't see any red flags.

\$\endgroup\$
0
\$\begingroup\$

Moving canvas is generally slow: differents browser has different performance issue, but moving just a big background image in enought to slow down the frame rate.

If you are supposed to perform real time, i suggest you to use webGL or equivalent.

How to check performance:

  • Time in drawing SVG: monitoring all changes may help to know what operation is expensive. Also check that you optimize your code with: id = mySvg.suspendRedraw(x) and mySvg.unsuspendRedraw(id). See http://dschulze.com/blog/articles/4/efficient-redrawing-on-svg-or-why-suspendredraw-is-a-lie and set svg quality to low/fast.
  • Time in database: never mix lot of rows with lot of data per rows. Divide queries in sub-queries that get ids and then get only interesting rows.
  • Javascript usually does not take lot of time, but if you expect a function is taking lot of time, monitoring it and try to optimize it (for example with asm.js)
\$\endgroup\$
1
  • \$\begingroup\$ -1 for "monitorize" (just kidding) \$\endgroup\$
    – jhocking
    Commented Sep 11, 2013 at 16:36
0
\$\begingroup\$

If i understand well you have all your gfx in canvas.
So it doesn't seem difficult to have the behaviour of the divs handled by some hand made class that will handle scene/layers. This way you can have the whole scene draw on a single canvas and avoid costly dom layout computations.

You might even have the context do a part of the job for you :

   // takes x,y,scale and a list of elements (which might be Scene)
   function Scene(x,y, scale) {
       this.elements = Array.prototype.slice.call( arguments, 0);
       this.x = x;
       this.y = y;
       this.scale=scale;
   }

   Scene.prototype.draw(ctx) {
       ctx.save();
       ctx.translate(this.x, this.y);
       if (this.scale !=1) ctx.scale(this.scale, this.scale);
       // rotate clip, ... here
       for (var i=0; i<this.elements.length; i++) {
           this.elements.draw(ctx);
       }
       ctx.restore()
   }

or you can have the elements compute their position based on their parent's.

Anyway i bet it will be much faster.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .