iOS 8 has now been released, and represents a radical improvement in the performance of HTML5 games in both Safari and the web view for native apps (such as used by PhoneGap). This is largely due to the fact iOS 8 now supports WebGL, which can significantly boost performance even for 2D games, and also supports WebGL shader effects. iOS 8 also introduces a new Javascript compiler, the Fourth Tier LLVM (FTL) JIT, which further improves Javascript logic performance. There is a small catch: due to bugs in this release of iOS, PhoneGap cannot yet take full advantage of the new performance improvements, but this is likely to be fixed in a future update. We've run a series of gaming benchmarks made with Construct 2 to quantify the performance improvements, and the results are impressive.
The performance tests
We ran four different performance tests:
- sbperftest ("Space Blaster performance test"): a real-world game running automatically and measuring the framerate over a period of about a minute. This is our favourite test since it probably best represents the real-world performance of a HTML5 game.
- renderperfgl ("renderer performance with WebGL"): an artificial test that measures how many sprites it can cram on-screen before the framerate drops to 30 FPS. It falls back to canvas2d if WebGL is unavailable (like the Construct 2 engine always does). This test is good at measuring the CPU overhead of issuing draw calls for lots of sprites.
- particles, a full-screen particle effect spawning about 850 particles and measuring the framerate. This is useful for measuring the framerate when making heavy use of particle effects.
- flyingalong, one of Construct 2's game templates, which we chose for its heavy use of tiled backgrounds which appear to be slow in iOS's canvas2d renderer (but much improved with WebGL).
We tested four platforms:
- Safari, the device browser
- PhoneGap 3.5, which makes use of the in-app web view, but as of PhoneGap 3.5 does not use the new faster web view control. A future version of PhoneGap should be faster and match the performance of Safari. More on this later.
- CocoonJS, a non-browser wrapper engine for comparison
- Ejecta, another non-browser wrapper engine for comparison (and the only non-browser wrapper we still officially support)
We tested both iOS 7.1 and iOS 8 on an iPhone 4S and iPad 2. These are the oldest devices supported by iOS 8, having been released in 2011. We chose these since it's useful to measure the low-end devices to get an idea what the minimum level of performance you can expect from any device running iOS 8. The latest devices are considerably more powerful, but to reach a broad audience it's important to know how weaker hardware will cope.
Performance in Safari
Safari can also make full use of JIT compilation to optimise Javascript for maximum performance. It also supports WebGL as of iOS 8. What impact does this have on game framerates? On the iPhone 4S:
And on the iPad 2:
We can immediately see significant improvements:
- sbperftest occasionally struggled on iOS 7, averaging 38 FPS on the iPhone 4S. With iOS 8 and WebGL support it can glide along at 60 FPS most of the time. This is a massive improvement for real-world games.
- Particle effects are considerably faster. On the iPhone 4S, performance is at least 4x better.
- The 'flyingalong' template is a simple game, but makes use of lots of Tiled Background objects. iOS's canvas2d renderer seems to have unusually poor performance rendering tiled images, only managing about 20 FPS on these devices. One of the advantages of our WebGL renderer is we can avoid poor quality canvas2d implementations and always use our own carefully tuned rendering code for best performance. It's successful here at bringing performance of this template right back up to a smooth 60 FPS. Games making use of tiled backgrounds or tilemaps should see very good performance improvements.
The performance of WebGL really shines when we measure how many sprites we can get on-screen at 30 FPS:
The improvement here is just incredible, and matches what we've seen on other platforms. Our WebGL renderer is extremely efficient and massively cuts down the per-sprite rendering overhead compared to canvas2d. This turns in to about 10x more sprite rendering capacity. Games which are high on sprite counts should see much improved performance on iOS 8.
Non-browser wrapper performance
Both CocoonJS and Ejecta are "non-browser wrappers": they do not use real browser technology, instead building a few game-oriented features on top of a standalone Javascript engine. We measured the performance of these engines between iOS 7.1 and iOS 8 running sbperftest.
There is no improvement - if anything, performance is slightly reduced, but is probably within a margin of error. Due to security restrictions on iOS, wrappers have typically not been able to use JIT compilation to fully optimise Javascript. This forces the Javascript engine to stay in interpreter mode, and can be several times slower than the JIT-optimising Safari browser. Often the slower Javascript engine puts a low cap on how well games can perform. iOS 8 finally allows apps using the web view to use JIT compilation (which PhoneGap needs to be updated to take advantage of - more on this later). However since the non-browser wrappers use a custom engine instead of the web view, they still appear to be stuck to interpreter mode and show no performance improvement at all on iOS 8.
We did run all the other tests on the wrappers as well, but the results are the same as above: little or no change. The Safari browser on iOS 8 now outperforms the wrappers on every test, often reaching 60 FPS where the wrappers cannot.
PhoneGap performance
When we measure PhoneGap performance, really we are measuring the in-app UIWebView control performance. This uses real browser technology, but has historically had severe performance problems: no GPU-accelerated rendering, and no JIT compilation of Javascript code - the worst of both worlds, and often so slow as to be impractical to publish games with. As of iOS 8, UIWebView can use GPU-accelerated rendering (and also has WebGL support), but still cannot JIT-compile Javascript for best performance. This means it still does not perform as well as Safari. However the good news is iOS 8 adds a new WKWebView control which can JIT-compile and therefore equal Safari's performance. PhoneGap needs to be updated to switch over from UIWebView to WKWebView to get these performance gains. This is yet to happen and appears to be held up by some bugs in WKWebView; hopefully this will be resolved in an update soon. In the mean time we tested PhoneGap 3.5 which uses the still-improved UIWebView control.
These results are only for the iPad 2 - the results follow an identical pattern on the iPhone 4S so there's nothing much to add by including those results. We ran the renderperfgl test to get an idea of the raw rendering performance.
There are a couple of interesting things to note here:
- PhoneGap performance is still massively improved in iOS 8, likely thanks to WebGL support: it can still manage 4x as many sprites as PhoneGap on iOS 7.
- PhoneGap on iOS 8 is now comparable performance-wise to the non-browser wrapper engines. It makes sense considering that UIWebView and the wrappers are on the equal ground of being able to use GPU-accelerated rendering but not JIT compilation. This is significant because as of iOS 8, switching to PhoneGap is no slower than using a wrapper.
- Clearly Safari still significantly outperforms PhoneGap. However once PhoneGap switches to WKWebView, we expect it to close this gap and match Safari's performance.
Already - even without the even faster WKWebView - this is a big change for publishing HTML5 games as native apps on iOS. There is nothing to lose performance-wise by switching from a wrapper to PhoneGap, but there's a lot to gain. Wrappers tend to cherry-pick a small selection of browser features, and miss out the rest. As a result they don't support lots of features that browsers do, such as Web Audio effects, web workers, form controls, XML parsing, and more. PhoneGap supports all of them, since it's a real browser engine. That means PhoneGap is actually equal in performance and significantly better with feature support. Our latest betas cover some ground with supporting ads and by the next stable release we expect to also support Game Center and IAP with PhoneGap.
When PhoneGap supports WKWebView, performance will again leap ahead up to Safari's standard. At that point using a wrapper will actually mean significantly degraded performance compared to PhoneGap. Therefore it appears to be a good idea to start using PhoneGap right away. It's not slower, already supports more features, and when PhoneGap updates to WKWebView you'll get another big performance boost without having to do anything!
The end of the wrappers
The non-browser wrapper engines CocoonJS and Ejecta were designed when the UIWebView was software-rendered and lacked WebGL support. Their main appeal was better performance due to their WebGL support and use of GPU-accelerated rendering. However they no longer have a performance advantage, and have a real feature support disadvantage. In the near future, they'll actually have a large performance disadvantage too. Given they will end up both slower and with poorer feature support than PhoneGap, it's hard to see what purpose they will serve in the long term. This was a significant factor in our decision to deprecate CocoonJS support in r179, and for similar reasons we expect to eventually deprecate Ejecta support as well in favour of PhoneGap.
On the Android side, Android L will bring the same performance and feature support to PhoneGap, including WebGL support. Android updates can be pretty slow to roll out though, but luckily in the mean time we have Crosswalk, which brings the full performance and capabilities of Chrome to native apps and supports Android 4.0+. We have already been recommending to using Crosswalk instead of wrappers for publishing to Android for similar reasons. In the long term Android L will eventually make Crosswalk unnecessary as well, but we'll keep supporting it for some time (likely years) to cover Android 4.0+ support.
What about older iOS versions?
Unlike Android, Apple are very good at quickly getting the majority of users up-to-date with the latest version of iOS. iOS 7 reached 74% market share in less than three months, and after a year currently stands at 92%. We expect iOS 8 to follow a similar pace of updates. We feel the improved feature support of using a real browser engine with a platform like PhoneGap is well worth the tradeoff of the minority of users using older software, especially when PhoneGap picks up WKWebView support and starts far outperforming the wrappers. The way we see it is you can either reach an extra minority of users, or sacrifice a lot of performance and features for the vast majority of users on the latest iOS 8. Either way iOS 8 and its successors will eventually reach near-enough 100% support that it won't even be giving up a tiny fraction of the market. This paints a very promising picture for the future: at last we will have a way to publish HTML5 games to both iOS and Android without giving up any features or performance.
Conclusion
iOS 8 brings huge performance improvements for HTML5 games today. It is of particular importance to games using WebGL shader effects, particle effects, high object counts, tiled backgrounds/tilemaps, or publishing with PhoneGap. In the long term it means fantastic support for native iOS games using PhoneGap, and the likely demise of non-browser wrapper engines.
Now every major desktop and mobile platform supports high-performance JIT-compiled Javascript and WebGL support (even Internet Explorer!). We've never been more sure that the web is the platform, and that HTML5 gaming is the future.