What a difference a Web View makes!

Kerri Shotts
Jan 18, 2017 · 6 min read

As you may recall, I mentioned that I was working on a faux emulator for a machine that never truly existed back in December of 2016. Things have progressed quite a bit since then with the Retroputer now having a fully working assembler for it’s own “6516 Assembly” language, Input/Output device support (with the keyboard as an example device), and even a very simple “bootstrap” ROM that sets up the initial screen configuration and even determines the initial color palette (which I think is quite pretty).

Now, Retroputer is by no means complete (it probably never will be — it’s a free-time project, and fun to fiddle with). On its own, it’s a play-thing, though hopefully a play-thing that can be used as a learning tool eventually, but that doesn’t mean it can’t be used to illustrate some differences in technology foundations.

The code behind Retroputer is not terribly complex, but it is emulating both a GPU (of sorts) and a CPU. The GPU is nothing compared to modern GPUs — a “video generator” would be the more appropriate term. It aims to generate a frame of 320x200 24-bit color sixty times per second using two HTML5 canvases (one visible at multiples of 320x200, the other is internal at 320x200 only). The CPU is, likewise, pretty archaic when compared to modern CPUs, but it is Turing complete, even if it doesn’t know about multi-threading, multiple cores, or floating point math. It’s important to note that the CPU gets whatever time remains after the screen is drawn in the browser.

So, no, Retroputer isn’t doing complex three dimensional graphics or computing complex equations. But what it is doing, it tries to do quickly — at 60fps, if possible. Whatever is time is left after drawing the screen is devoted to the processor. This does let us draw some conclusions about performance across different web views since the web view is having to render quickly changing imagery and is pegging a single core to the max (JavaScript is single-threaded, unless one implements web workers).

I should note that Retroputer’s performance is highly variable depending upon the configuration of the screen (Retroputer can support complicated frame layouts), and the instructions being processed (there are some bulk operations that can take considerable time), but we’re keeping this demonstration simple. The idea is this: fill screen memory with the Retscii character set as quickly as possible ad infinitum. The 6516 assembly code for this is really simple.

Most of my day job involves working with mobile hybrid application development, primarily using Apache Cordova. Cordova uses the native web view on the target platform to run packaged JavaScript, HTML, and CSS while also providing plugin support to enable JavaScript to utilize native device features.

For a long time, iOS devices only had one web view: UIWebView. With the advent of iOS 8, a new web view was introduced: WKWebView. For simple apps, one probably wouldn’t notice the difference between the two. However, there are many differences, not least of which is the JavaScript engine.

In WKWebView, JavaScript is just-in-time compiled, which can often improve your app’s performance, especially over code paths that are repeated many, many times. UIWebView does none of this, and it turns out to be pretty slow. The difference is usually touted as WKWebView being about three times as fast as UIWebView, though real-world scenarios vary these results quite a bit.

You’re probably on to what I wanted to determine: how fast does Retroputer run this simple program on an iOS device (in my case, an iPad Pro 12.9-inch model) using WKWebView versus the same thing happening on a UIWebView, right? If so, you’re absolutely right. I even made a quick, short video about it.

What a difference a Web View makes (Retroputer UIWebView vs WKWebView)

The difference is stark, to say the least. First, UIWebView’s performance is absolutely abysmal. I mean you can watch the emulator draw the characters to screen over the course of several seconds. Second, Retroputer is incapable of even reaching sixty frames per second, no matter how hard it tries. Retroputer managed roughly 41 frames per second, executing only 100 instructions per frame, which comes to roughly 0.0041 MIPS, or million instructions per second.

To put that number into context, even my beloved Commodore 64 can do better than that. According to Wikipedia, it could manage 0.43 MIPS — two orders of magnitude faster than UIWebView’s performance. Your laptop today is several orders of magnitude faster yet.

Next, I ran the experiment with WKWebView. Using Mobile Safari accomplishes the same thing, though I did verify that the numbers hold true when using WKWebView from an iOS app as well (and they do). The difference is vast. Retroputer is capable of averaging at 59 frames per second, and executes, on average, sixty thousand instructions per frame, which comes out to about 3.54 MIPS. Not amazing when compared to your laptop of course, but this is performance roughly on par with a Motorola 68010 at 16.67 MHz and and about 1 MIPS shy of an i386DX at 33MHz (again, according to Wikipedia).

The performance increase from UIWebView toWKWebView here is absolutely ridiculous. This is clearly not something you should expect in most applications. WKWebView is able to optimize the code paths like crazy because it sees them so often and the data that’s flowing through happens to be simple integers and only simple operations are executed. But still, that difference is really big!

But then I wondered — how much is the canvas processing contributing to the problem? Aside from drawing the internal canvas to the visible canvas, there’s a lot of JavaScript code which is solely responsible for deciding which pixel is lit and the color to assign to it. If JavaScript performance is slow, then calculating what should be drawn to the canvas is eating up valuable processing time, right?

So I turned off the screen rendering portion, and it turns out that yes, calculating what ends up on the canvas does take a considerable amount of time. So that’s largely what’s leading to the miserable 0.0041 MIPS when using UIWebView. But even when the screen calculations are removed, the UIWebView can only sustain 0.13 MIPS. Much faster than 0.0041 to be sure, but no where near as fast as WKWebView (which, when not updating the canvas can manage 4.24 MIPS). This follows, because we expect UIWebView to have poor JavaScript performance, and the screen updating routines are, of course, JavaScript. In this case, WKWebView is over 32 times as fast as UIWebView.

Here are the final numbers in table form for easier digestion:

Technically the FPS on the right are meaningless; consider them equivalent to function executions where the function finishes within about 14 milliseconds

I should mention that none of this is scientific in any way, shape, or form. It’s a fun little experiment, and it the results themselves depend heavily upon the initial setup — in this case, an unoptimized emulator where the WKWebView optimizer has a chance to shine due to the highly repetitive (and simple) nature of Retroputer’s code execution. You would, and should, not expect these results in the real world. Here, let me make that more obvious:

You should not expect these results in the real world!

But it does illustrate the point: the foundation upon which we build our apps can often play a huge part in the performance of our app. For apps that aren’t dependent upon performance, the user won’t see much difference. But for apps that are, or for apps trying to hit 60fps when, say, scrolling a long list, that difference quickly comes into play, and it can be quite stark.

Postscript:

In case you’re curious, my iPhone 6 runs Retroputer only a little slower than the iPad Pro (60 fps,~2.85 MIPS). My 15-inch MacBook Pro Retina (Intel) from 2014 comes in at just about the same speed as the iPad Pro (ARM). Interesting, I think, and perhaps indicative of the future of Apple’s laptops? OK, so my MBP has way more cores, and an emulator is not Photoshop or some 3D rendering software, but what if an iPad Pro had the same number of high performance cores? Hmm…!

 by the author.

Kerri Shotts

Written by

JavaScript fangirl, Technical writer, Mobile app developer, Musician, Photographer, Transwoman (she/her), Atheist, Humanist. All opinions are my own. Hi there!

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade