HTML and CSS Reference
Keeping Canvas Applications Stable
It is very hard to keep canvas applications stable. As I mentioned, compatibility issues are critical. Additionally,
mobile devices don't have a large amount of memory. And finally, despite PC browsers having no power limits, for
mobile devices you have to take care regarding battery usage.
If you want to create a technical one-time demo, this section is not so important. But if you are planning to create
games, which many users play for a long time, it's important to support several devices, avoid crashing browsers, and
prevent excessive battery consumption. I will show you techniques to work around these issues in this section.
There are less compatibility issues on Canvas than CSS. Nevertheless we have to struggle to support a range of
browsers on existing devices. It is especially tough to support Android legacy browsers; it will annoy you very much.
As mentioned earlier, Android makers customize their browser excessively, so you may face many kinds of problems
around compatibility issues. For example, the simple code in Listing 16-16 won't work well on several devices.
Listing 16-16. A Famous Troublesome Code
ctx.clearRect(0, 0, w, h);
If you face compatibility issues, you should throw away any preconceived notion that such simple code must
work well, and be completely suspicious about browser implementations.
To find troublesome code, it's reasonable to comment out several lines or blocks of code from the entire code to
locate the problem via bisecting. Next, try to make the smallest problem code, which can reproduce the same issue.
Finally, you will find the workaround to avoid the problem. The workaround for Listing 16-16 is shown in Listing 16-17.
Listing 16-17. Workaround
ctx.clearRect(0, 0, w + 1, h + 1);
To find out the real problem, it's good idea to try to think like a browser writer. Imagine what kind of processing
goes on inside the browser that may cause the problem. To get the fastest result, consider how you would implement the
browser. It's the easiest way to fix the issue: you make a hypothesis about implementation, and validate it time after time.
Sometimes the GPU causes the compatibility bugs. There is no option to disable GPU rendering, but you can
disable it by just setting the target canvas width or height to more than 2048px. It turns off GPU rendering, and turns on
CPU rendering. If you find a bug in GPU rendering, you can avoid it by preparing a large canvas for particular devices.
Again, you'll need to struggle a great deal to support all Android devices. Therefore, it's sometimes a good idea to
give up supporting devices whose market share is insignificant.
It's important not to consume too much memory, because mobile devices have very limited amounts of RAM. If you
use memory over the limit, the browser will crash, will freeze, and will skip drawing in the browser. When you face
those kinds of problems, you should investigate memory usage.
You must also confirm that garbage collection successfully collected the unused canvases, especially when you
use In-Memory Canvas. Some mobile browsers seem not to collect canvas elements at all, so if you find this kind of
problem, you need to prepare a large In-Memory Canvas and reuse it again and again.
You also need to be aware of memory leaks. Every image and canvas consumes lot of memory, so you should
release the reference to them properly. You can check the memory leak with your PC using the Heap Snapshot feature
in Chrome Dev Tools.