My game is slow on HTML5 (likely due to rendering), how can I optimize it given these details?

  • My game is slow on HTML5, probably because of rendering. How can I optimize it, given the following information? The game is here, and the source code is here.

    I believe the following information is relevant:

    General Details

    • Target framerate is 60FPS, non-negotiable.
    • Performance on desktop (both with C++ and Neko) is perfectly adequate. Haven't tested mobile yet.
    • The performance problems are on the HTML5 target, using blit rendering. In fact, I think the problem is ultimately the rendering.
    • I don't use Flash at all.
    • The number of draw()s per frame varies, but is at most 180.
    • Almost all graphics are on one texture atlas.
    • I'm using the Git versions of Haxe, HaxeFlixel, and all add-ons.
    • The game field is 320x240.
    • The camera does not move, and uses pixel-perfect rendering.
    • I do not use a fixed timestep.

    Game-Related Details

    • I believe the culprit is the big grid of blocks that makes up most of the screen.
    • The grid holding all the blocks is represented as a subclass of FlxTypedSpriteGroup.
    • There are at most 144 blocks (12x12), and the game's mechanics involve clearing them. When this happens, a block is kill()ed.
    • When the player can't make any more moves, the grid refills; no new blocks are created, they are all recycle()d.
    • Each block is an individual FlxSprite (well, actually, a subclass that holds game-specific info, but nothing about rendering).
    • Each block can take on one of six different still frames (the block colors) and has two animations. These graphics are all on the aforementioned texture atlas.
    • Physics and collisions are not used; all blocks are moved via FlxTween.
    • Every time the player takes a turn some (but not all) of the blocks move simultaneously. This is when the game slows down the most (from 60FPS to about 45 or so).
    • The blocks don't move if the player takes no action.
    • If the player tries to make an invalid move, the blocks s/he clicked will shake in place a little.

    Is there some optimized form of rendering (usable in blit mode) that I'm not aware of? Any tips would be greatly appreciated.

  • Not sure about html5, but the built-in debugger can help you:

    Look at the "update" and "draw" values (time representation). For the desktop build values of 1ms or lower are good. In the screenshot I have "update" of 8.4ms, which means that there is something to optimize in the game logic (update() functions). Draw is for rendering.
    Then you can comment out the code with the logic or the rendering and compare the values to the previous ones.
    When the sum of the values is over 1/60 seconds (about 16ms), it's impossible for the engine to render at 60 FPS on this PC.

  • Did you try that on desktop with Neko or with C++? (Neko is slower than C++)

  • It's a screenshot for my game, didn't try yours. Sadly, the binary version is a release build

  • On my machine I'm getting about 1.7ms per update() on a debug Neko build on Ubuntu 16.04, with an i5-2410M CPU at 2.30GHz. On this same build I get about 4.5ms per draw(). So update() is not the bottleneck in my project, it's draw().

    On the same machine, with a debug HTML5 build, I get about the same...? But the FPS reading still frequently drops under 60. Now I'm confused. I do get higher CPU usage, though, and my fan does spin up whenever I play my game in-browser (and your game, too, for that matter.)

  • Then at the time of the FPS drops your timings were more than 16 ms apparently?
    Try to move your "blocks" forever, like a benchmark.
    There is also a dedicated tool for Haxe profiling called hxScout, but it didn't use it much.

  • Possibly, maybe the numbers just didn't show in the graph due to the timing being too coarse.

    I'll give hxScout a try, thanks!

  • @JesseTG Hey, there is one more thing!
    I just found that there is a button in the right-top corner of the debugger, that adds the new graphs.

    And this was a great revelation :D

  • @starry-abyss Yep, knew about that, but thank you anyway.