Blog

HTML5 Canvas and Browser Performance

Adobe Flash dominates online interactive experiences. But should it?

Recently, there has been lots of hype surrounding the topic of Flash vs. HTML5. Apple released the iPad this Spring–Adobe Flash player incompatible–splitting the internet into two battling sides: Flash and HTML5. Previous Apple products have not supported Flash and Steve Jobs has publicly shared his thoughts regarding this subject. Obviously, neither will immediately be phased-out, but it is very important that developers choose the right tool to get the job finished.

Adobe Flash Player is widely used to render animated graphics across the internet. HTML5’s canvas 2d context is able to dynamically draw graphics to a canvas element using Javascript. Essentially, its functionality directly competes with many of the core features Macromedia’s/Adobe’s Flash Player has shown off for the past 14 years. Choosing the right platform to provide content to a user can be tricky since the areas of performance are sometimes shady–especially when two large companies, like Apple and Adobe, are dumping loads of money towards publicly shaming one another.

Yesterday, I built a small JS app that renders canvas animations that are focused on different performance areas. For each action, a setInterval() is initialized at one millisecond (calling the function repeatedly, as fast as it can). After doing so, everyone at the Quickleft office ran the app through different hardware configurations and browsers. Here are the results:

(If you are itching to see for yourself): Code

Circles

//random location var x = Math.floor(Math.random()$canvas.w), y = Math.floor(Math.random()$canvas.h), radius = Math.floor(Math.random()*200);

//draw $context.beginPath(); $context.arc(x, y, radius, 0, Math.PI * 2, false); $context.closePath(); $context.stroke();

  • 3 math random calculations
  • 1 arc draw

JSFPS:

FirefoxChromeSafariOperaAndroid Browser*SkyfireSafari Mobile
iPhonexxxxxx15
Motorola Droidxxxx1013x
Dell Netbook (1)1775xxxxx
Macbook Pro Core 2 (2)5517095210/96**xxx
Macbook Pro Core i7 (3)8023095280/96***xxx
  • * Pre Android 2.2 (Pre-Froyo/Pre-ChromeV8JS Engine)
  • ** Before and After 7,000 draws
  • ** Before and After 10,000 draws
  • 1 Intel Atom n270 1.60 GHz
  • 2 Intel Core 2 Duo 2.26 GHz
  • 3 Intel Core i7 2.66 GHz

Calculus Tween

CANVAS.draw.clearCanvas();

//draw $context.beginPath(); $context.arc($i['x'], $i['y'], ($canvas.h/10), 0, Math.PI * 2, false); $context.closePath(); $context.stroke();

//count $i['x']++; $i['y'] = Math.sin($i['x']/20)*($canvas.h/4) + ($canvas.h/2);

//reset if($i['x'] > $canvas.w + 30) $i['x'] = 0;

  • 1 canvas clear
  • 1 arc draw (minor math logic)
  • Sine calculation / iterator

JSFPS:

FirefoxChromeSafariOperaAndroid Browser*SkyfireSafari Mobile
iPhonexxxxxx7
Motorola Droidxxxx813x
Dell Netbook (1)2092xxxxx
Macbook Pro Core 2 (2)5716088214/96**xxx
Macbook Pro Core i7 (3)8022495360/96***xxx
  • * Pre Android 2.2 (Pre-Froyo/Pre-ChromeV8JS Engine)
  • ** Before and After 7,000 draws
  • ** Before and After 10,000 draws
  • 1 Intel Atom n270 1.60 GHz
  • 2 Intel Core 2 Duo 2.26 GHz
  • 3 Intel Core i7 2.66 GHz

Gradient

//draw var gradient = $context.createRadialGradient($canvas.w/2,$canvas.h/2,0,$canvas.w/2,$canvas.h/2,$canvas.w/2); gradient.addColorStop(0, 'rgb('+Math.floor(Math.random()256)+','+Math.floor(Math.random()256)+','+Math.floor(Math.random()256)+')'); gradient.addColorStop(1, 'rgb('+Math.floor(Math.random()256)+','+Math.floor(Math.random()256)+','+Math.floor(Math.random()256)+')'); $context.fillStyle = gradient; $context.fillRect(0, 0, 800, 400);

  • 1 gradient set (minor math logic)
  • 6 math random calculations
  • 1 gradient rectangle fill

JSFPS:

FirefoxChromeSafariOperaAndroid Browser*SkyfireSafari Mobile
iPhonexxxxxx4
Motorola Droidxxxx510x
Dell Netbook (1)540xxxxx
Macbook Pro Core 2 (2)36608868/54**xxx
Macbook Pro Core i7 (3)50989794/80***xxx
  • * Pre Android 2.2 (Pre-Froyo/Pre-ChromeV8JS Engine)
  • ** Before and After 7,000 draws
  • ** Before and After 10,000 draws
  • 1 Intel Atom n270 1.60 GHz
  • 2 Intel Core 2 Duo 2.26 GHz
  • 3 Intel Core i7 2.66 GHz

What does all of this mean?

First, let me explain JSFPS. This is a count of recursion cycles–how many times the function gets called and processed per second. This is not true Frames Per Second for multiple reasons: JS isn’t actually writing this fast to the screen; also, most monitor refresh rates are ~60Hz (60 Draws / Second), so even if JS were writing faster than 60FPS, you wouldn’t be able to tell. (That’s right, your rig that renders Crysis at 200FPS really isn’t that cool after all…)

As you can see, our JavaScript processing king is Google Chrome. I cannot explain to you how fast Chrome is when it comes to JavaScript–just see for yourself. (Try it out in Chrome vs. Firefox). V8, Google’s open source JavaScript engine, is wicked fast. (Almost 300% faster in our tests than TraceMonkey–Firefox’s latest JS engine) This is a huge step up from previous browsers’ JavaScript processing. The newest Android release (2.2 Froyo) will implement Google’s V8 engine directly in the mobile browser which will have a large impact on mobile JS processing.

But wait! Opera beat V8’s JS speed! Not really. Opera begins rendering the animations at up to 360 JSFPS, but after a few seconds of data crunching the recursion crashes to a much slower rate. Apparently Opera is great at crunching through Math Calculations and Memory Allocations, but isn’t doing any garbage collection. Essentially, Opera flies through the first few thousand iterations, throwing data wherever it has room, but eventually fills the allocated Memory and begins cleaning up unused RAM. This is great for short calculations, but eventually Opera has to stop and catch its breath.

Most Flash animations are rendered at 24-30FPS. Research has shown that humans can observe animated motion at speeds up to about 24FPS. Looking at these results, for most situations, Javascript and HTML5 are very well suited to compete with Adobe Flash Player. The Adobe Flash programming environment is obviously much more user friendly to develop in, but it sure is nice to be able to experience these animations without downloading a proprietary software platform. Oh, and did I mention this awesomeness works on our iPhones, iPads, and pre-2.2 Android phones?

The war between HTML5 and Flash should not be focused on which technology should die off, but rather how to choose the correct platform for each project. Just keep in mind that at this point in HTML5’s development (particularly, the Canvas element), this technology is meant to be used in unique situations, not for everything. Here at Quickleft, we strive to show the power of HTML5 and Javascript when our apps call for something special! (Check out Friends With You).

I love HTML5/JS madness, so show me anything cool you have built using HTML5 Canvas animation @nico_valencia #HTML5.