# Performance of many canvas drawImage calls is very slow

I'm developing a top-down 2D tile-based canvas game. I have a single sprite sheet of all my tiles, and then a JSON tile map array of where they're placed.

Previously I would render all the layers of tiles out to a single canvas element once, and then re-render that every frame. This would give me 300+ FPS because it would just be a single draw call each frame to redraw this canvas.

However, the issue with this is that the map is not just a "flat" image. Sometimes tiles need to be destroyed, or sometimes the player needs to stand behind certain tiles (such as when the player is above them), which doesn't seem possible if the map is just a static image.

As a result, I believe I instead need to re-render all the tiles every frame. However, even if I only re-render the tiles that the user can see, the FPS drops tremendously. With just two tile layers and a 100x100 map, the FPS drops to 20.

I would have assumed that, despite there being 100 * 100 * 2 canvas.context.drawImage calls per frame, that it would still be fine, because it was leveraging the GPU, and I'm using a single sprite sheet, so there should be no texture swapping. Apparently this is not the case.

I was looking for a way to possibly speed this up, but the recommendations seem to be extremely heavy-handed and opinionated libraries like three.js and pixi.js. These libraries would be great, except they do too much. In PIXI and Three.js you need to add objects to a scene and they're automatically redrawn each frame. This is not what I need, as my current ECS architecture demands an immediate-mode renderer, and I have my own scene graph already, so I can't (and don't want to) use theirs.

Is there a solution here? The only thing I really need to do is draw images clipped from a spritesheet quickly. Can this be done using immediate-mode rendering? Or is it doomed to be 20 FPS?

What do you think about rendering 2-3 states of the game world? Like, one which is "the stuff below the player", another which is "the stuff above the player", and more to suit your needs. Then simply render these in their respective order stuff below player -> player -> stuff above player
Then instead of re-collecting the image data every time a modification is made to the game world, perhaps there's another solution where you can manually edit the image's imageData object using math to near-instantly hunt down the exact pixels which need updating? This part is a bit fuzzy, but perhaps you could make it work? (Resulting in 2-3 calls to the renderer every frame, and a single one-tile-wide edit to image data every time a world-changing action is taken)