Under the Hood: Bubbles

In an earlier post we discussed JavaScript performance improvements introduced in IE10. Today we published Bubbles, originally inspired by Alex Gavriolov’s simulation BubbleMark, to explore some of these advances. The current version has been greatly expanded to take advantage of the new features of the Web platform and includes characteristics common to HTML5 games. In this post we peek under the hood to see how the demo is constructed and examine the main factors that affect its performance.

Screen shot of Bubbles demo running in Metro style IE10 on the Windows 8 Release Preview
Bubbles demo running in Metro style IE10 on the Windows 8 Release Preview

The Structure of the Demo

The demo consists of a number of animated bubbles floating through space. At the core is a relatively simple JavaScript physics engine. On every animation frame, about 60 times per second, the physics engine recalculates the positions of all bubbles, adjusts the speed of each bubble by applying gravity, and computes collisions. All these computations involve intensive floating point math. Each bubble is represented on screen by a DOM image element to which a CSS transform is applied. The image is first translated around its origin, and then scaled dynamically to produce the effect of the bubble inflating. In JavaScript, every bubble is represented as an object with accessor properties, as introduced in ECMAScript 5.

Behind the floating bubbles is a large image, which starts off occluded by a fully opaque mask rendered in a <canvas> element. Whenever two bubbles collide, a portion of the occluding mask is removed by applying a Gaussian filter to the mask’s opacity component to produce a diffuse transparency effect. This process also involves many floating point multiplications, which are performed on elements of Typed Arrays, if supported by the browser.

Over the floating bubbles rests a touch surface, which responds to touch input if supported by the running browser or mouse events if not. In response to touch simulated magnetic repulsion is applied to the floating bubbles scattering them around.

Efficient Animation

In IE10 we introduced support for the requestAnimationFrame API. When building JavaScript applications with animation we continue to recommend using this API (instead of setTimeout or setInterval) on browsers that support it. As discussed in a previous post exploring how to make the most of your hardware, this API allows you to achieve maximum frame rate supported by the available display while avoiding excessive work that would remain invisible to the user. By doing the minimal number of operations to deliver the best user experience, you can save battery power. IE10 Release Preview supports this API without vendor prefix, but the prefixed version is also maintained for compatibility with earlier IE10 preview releases. The Bubbles demo uses this API and falls back to setTimeout when it is not available.

Demo.prototype.requestAnimationFrame = function () {

var that = this;

if (window.requestAnimationFrame)

this.animationFrameTimer =

window.requestAnimationFrame(function () { that.onAnimationFrame(); });


this.animationFrameTimer =

setTimeout(function () { that.onAnimationFrame(); }, this.animationFrameDuration);



Demo.prototype.cancelAnimationFrame = function () {

if (window.cancelAnimationFrame)





Converting DOM Values from Strings to Numbers

JavaScript is very flexible and includes a range of automatic conversions between values of different types. For example, string values are automatically converted to number values when used in arithmetic operations. In modern browsers, this convenience may come at a surprisingly high performance cost. Type specialized code emitted by state-of-the-art JavaScript compilers is very efficient in arithmetic on values of known types, but incurs very high overhead when it encounters values of unexpected types.

When the Bubbles demo is loaded, the numberOfBubbles property starts off with a value of 100. On every animation frame, the position of each bubble is adjusted:

function Demo() {

this.numberOfBubbles = 100;




Demo.prototype.moveBubbles = function(elapsedTime) {

for (var i = 0; i < this.numberOfBubbles; i++) {

this.bubbles[i].move(elapsedTime, this.gravity);



When the user selects a different value in the UI, the value of the numberOfBubbles property must be adjusted accordingly. A straightforward event handler may do it like this:

Demo.prototype.onNumberOfBubblesChange = function () {

this.numberOfBubbles = document.getElementById("numberOfBubblesSelector").value;



This seemingly natural way of reading the user’s input results in about 10% overhead in the JavaScript portion of the demo. Because the value obtained from the drop down and assigned to numberOfBubbles is a string (not a number), it has to be converted to a number on every iteration of the moveBubbles loop for every frame of the animation.

This demonstrates that it’s a good practice to explicitly convert values extracted from the DOM to numbers before using them in arithmetic operations. Values of DOM properties are typically of type string in JavaScript and the automatic string to number conversions can be quite expensive when done repeatedly. A better way to update numberOfBubbles based on user selection, as found in the demo, is as follows:

Demo.prototype.onNumberOfBubblesChange = function () {

this.numberOfBubbles = parseInt(document.getElementById("numberOfBubblesSelector").value);



Working with ES5 Accessor Properties

ECMAScript 5 accessor properties are a convenient mechanism for data encapsulation, computed properties, data validation, or change notification. In the Bubbles demo, whenever a bubble is inflated the radius is adjusted, which sets the computed radiusChanged property to indicate that the bubble’s image needs to be resized.

Object.defineProperties(Bubble.prototype, {


radius: {

get: function () {

return this.mRadius;


set: function (value) {

if (this.mRadius != value) {

this.mRadius = value;

this.mRadiusChanged = true;






In all browsers, accessor properties add overhead as compared to data properties. The precise amount of overhead varies between browsers.

Minimizing Access of the Canvas ImageData

It’s a well-established practice to minimize the number of calls to DOM in loops on the critical performance path. For example, if the Bubbles demo updated the location of every bubble by looking up the corresponding element in the document (as below), performance would be adversely affected.

Bubble.prototype.render = function () {

document.getElementById("bubble" + this.id).style.left = Math.round(this.x) + "px";

document.getElementById("bubble" + this.id).style.top = Math.round(this.y) + "px";



Instead, the element corresponding to each bubble is cached in the bubble object in JavaScript once, and then accessed directly on every animation frame.

Bubble.prototype.render = function () {

this.element.style.left = Math.round(this.x) + "px";

this.element.style.top = Math.round(this.y) + "px";



What may be less clear is that care must be taken to avoid similar overhead when working with <canvas>. The object obtained by calling canvas.getContext("2D").getImageData() is also a DOM object. The code below could be used in the demo to draw the bubble collision effect to the canvas. In this version imgData.data is read on every iteration of the loop, which requires a call to the DOM and adds great overhead.

BubbleTank.prototype.renderCollisionEffectToCanvas = function(px, py) {

var imgData = this.canvasContext.getImageData(/*...*/)


for (var my = myMin; my <= myMax; my++) {

for (var mx = mxMin; mx <= mxMax; mx++) {

var i = (mx + gaussianMaskRadius) + (my + gaussianMaskRadius) * gaussianMaskSize;

imgData.data[4 * i + 3] = 255 * occlusionMask[(px + mx) + (py + my) * canvasWidth];



this.canvasContext.putImageData(imgData, px - gaussianMaskRadius, py - gaussianMaskRadius);


A better way to update the <canvas> image data is by caching the data property as in the following code snippet. The data property is a typed array (PixelArray) and can be accessed very efficiently from JavaScript.

BubbleTank.prototype.renderCollisionEffectToCanvas = function(px, py) {

var imgData = this.canvasContext.getImageData(/*...*/)

var imgColorComponents = imgData.data;


for (var my = myMin; my <= myMax; my++) {

for (var mx = mxMin; mx <= mxMax; mx++) {

var i = (mx + gaussianMaskRadius) + (my + gaussianMaskRadius) * gaussianMaskSize;

imgColorComponents[4 * i + 3] =

255 * occlusionMask[(px + mx) + (py + my) * canvasWidth];



this.canvasContext.putImageData(imgData, px - gaussianMaskRadius, py - gaussianMaskRadius);


Using Typed Arrays to Store Floating Point Numbers

In IE10 we added support for Typed Arrays. When working with floating point numbers it is advantageous to use Typed Arrays (Float32Array or Float64Array) instead of JavaScript arrays (Array). JavaScript arrays can hold elements of any type, but typically require that floating point values be allocated on the heap (boxing) before being added to the array. This affects performance. To achieve consistently high performance on modern browsers use Float32Array or Float64Array to indicate the intent of storing floating point values. Doing so you help the JavaScript engine avoid heap boxing and turn on other compiler optimizations, like generating type specialized operations.

BubbleTank.prototype.generateOcclusionMask = function() {

if (typeof Float64Array != "undefined") {

this.occlusionMask = new Float64Array(this.canvasWidth * this.canvasHeight);

} else {

this.occlusionMask = new Array(this.canvasWidth * this.canvasHeight);




The example above shows how the Bubbles demo uses Float64Arrays to hold and update the occlusion mask applied to the canvas hiding the background image. If the browser doesn’t support Typed Arrays, the code falls back on regular arrays. The gains from using Type Arrays in the Bubbles demo vary with settings. In a medium-sized window in IE10, Typed Arrays improve the overall frame rate by around 10%.


In this blog post we explored the newly published Bubbles demo and examined how it takes advantage of dramatic gains in JavaScript execution the IE10 Release Preview. We shared a few important techniques to achieve good performance in animation-based applications. For more technical details about the changes in the JavaScript runtime (Chakra) in IE10 Release Preview, please, refer to the earlier post. We are excited about the greatly improved performance and new capabilities available in IE10 Release Preview and we hope they will allow for ever more fascinating applications to be build using Web standards and technologies.

—Andrew Miadowicz, Program Manager, JavaScript

Comments (30)

  1. Arieta says:

    It does not work in IE10pp2 under Windows 7: the animation stops after a split second and you have to pause and start it again, after which it will lock up in a split second again.

    When will you release a Windows 7 version of IE10?

  2. Luandersonn says:

    The "Internet Explorer 10" will release for Windows 7? If not, will be a tremendous shot in the foot.

  3. Brian LePore says:

    Is it just me, or does that DOM values conversion portion of the article seem out of place? I mean, yes, it is interesting and I don't think many developers realize such and it will improve the web, but that optimization really shouldn't be specific to IE10, is it?

  4. Dave says:

    The comment for is still broken! – please fix this ASAP we are tired of having to tell you this!

    Since you seem incapable of adding a button type=submit to the page please get in touch with the makers of community server and ask them for an update that doesn't use faulty ASP postback techniques to submit the comment form.

    This has now gone beyond rediculous this should have been fixed over 5 years ago!!!!

  5. Win8 Vista 2.0 says:

    Still asking for Win7 IE10? It's obvious MS will not release it, IE10 is Win8 only. Buy Win8 Vista 2.0 to get IE10, NOT.

  6. pmbAustin says:

    * Need to release a preview of IE10 for Win7 ASAP

    * Need to support favorites/bookmarks in IE10-Metro ASAP

    * Need to support more UI customization in IE10-Desktop ASAP (separate search box, move home/favorites/tools buttons to left, etc)

    * Need to fix embedded Flash's support of videos (most streaming videos embedded in pages outside of YouTube show blank, sound only, no picture… in both Metro and Desktop… this worked fine in IE10-Desktop in the CP and is broken in the RP)

    * Need to commit to releasing updates to IE10 (including new standards support) at least every six months… not every two or three years

    * Need to support Silverlight in IE10-Metro (like Flash) to avoid situations where THIS is a user's first experience with Win8/IE10/Metro:

  7. pmbAustin says:

    And I managed to hit post without pasting my link… so repeating:

    * Need to support Silverlight in IE10-Metro (like Flash) to avoid situations where THIS is a user's first experience with Win8/IE10/Metro:  http://www.infoworld.com/…/ie10-windows-8-even-microsoft-cant-make-it-work-195293

  8. gianfredo says:

    @Win8 Vista 2.0

    Meh, it took me some time to get that w7-ie10 joke they made.

    But I personally liked vista, infact I bought w7 just to be able to test with IE10 previews, of which of them none were released since.

    Obviously they need to focus on w8. I've been told that even the staff that used to fix broken commenting systems now works on w8 instead (IIRC on WinJS). They are so busy, they didnt even have time to upload a windows-to-go image.

  9. ABC News says:

    We just watched Nick Walenda walk across a tight rope over Niagara Falls from the USA to Canada!


    Do you know what would be more amazing?! If the IE Blog actually fixed their comment form so that  users and developers that want to share their opinion about IE, and report bugs on IE can actually do so without fear of losing data!

    Thank you,

    Signed ABC News and the millions of viewers around the world.

  10. No silverlight says:

    I keep hearing people whine about no silverlight in metro IE.

    For those whining – get over it! Silverlight is dead. Dead technology and completely in suitable for a tablet environment.  It didn't make it to the phone, the iPad, the PlayBook, the galaxy tab… Nada.

    If you are a developer and you made the catastrophic mistake of building and depending on silverlight then you messed up majorly! We're talking worthy of a post on the daily wtf epic fail.

    Vendor lockin on proprietary closed source software is easily avoidable and in 2012 if you make a design descision to avoid open source and jump in bed with a non-open technology you are incredibly foolish… In most companies these actions are full justification for dismissal.

    Again I can't believe that any developers are complaining about Microsofts decision to abandon dead technology on tablets.  I rarely congratulate Microsoft on their descisions but this one was one of their best!

  11. Lewald says:

    HTML is dead tech. from basic.

    Please Silverlight. Otherwise we didn´t Support Metro. HTML make no sense on Tablets.

    Thats the fact. HTML is no real standard.

  12. Lewald says:

    Demo run with poor 14 Frames on i5 Windows 8 Consumer. Thats the Speed with HTML — 🙂

  13. Grant says:

    HTML isn't dead.. In fact it's booming! HTML5 is the only language (ok HTML/CSS/JS) that works great on desktops (win, Mac, or Linux) on phones (android, blackberry, iPhone, even Nokia, and now even on windows phone), and on tablets (galaxy tab, PlayBook, iPad, WebOS, Kindle, and even new windows8 tablets if they ever fix the ARM problem and ship)

    Silverlight on the other hand never took off.  The web didn't accept a proprietary multimedia format from the company that refused to follow standards.. There was a conflict of interest for Microsoft to even make the player available on different browsers in windows let alone competing operating systems.

    The only silverlight I have ever even seen being used is on Microsoft owned websites and that's only because Microsoft forced the technology on their internal projects.

    Silverlight never made it to a single mobile platform and we are talking about a 7 year old industry!!!

    Silverlight is dead, stop trying to wake the horse.

  14. Lewald says:

    You said "HTML5 is the only language (ok HTML/CSS/JS) that works great *****"

    You wish that this is true. But reality show us that this is not true. HTML 5 is no Standard at this time.

    And JavaScript and CSS dind´t work well on different Browsers and  different Platforms.

    The Layout Engine of HTML and CSS is brocken by Design.

    The wish you offer here will never come in real live. Every HTML Site has massive Problems with different Browsers and different Devices.

    Only one Content Firewall in Office and your App will not work.

    That is the reality

  15. pmbAustin says:

    @No silverlight, I know Silverlight is dead.  That's irrelevant.  Did you read the link I posted?  Here it is again, just so you can… this is about the whole "it just works" philosophy that Win8 and IE10 currently fail at… if you really believe things should just work, then you need one last hurrah for Silverlight.  Because the web isn't ready for it to just disappear just yet.


    You either need to do this, or admit that you don't care about things "Just working" and you're okay with torturing non-technical users to the point they give up in frustration and either go back to Win7 or skip town to iOS or OS X.

  16. Ark-kun says:


    I really like the standards support in IE. But the browser (user experience) is neglected. I get lot's of problems and irritating behavior.

    Tabs jump around.

    Lot's of "Internet Explorer stopped working" when closing the browsers.

    Losing my previous session.

    IE using 10000 GDI objects and many thousands of handles.

    Constant background kernel-mode CPU usage which even makes my mouse lag on 6-core CPU.

    "Save Image As" dialog doesn't remember the last sae location defaulting to LibrariesPictures

    Inability to enable and reopen popup withour page refresh.

    Some pages still cannot be saved.

    In Windows 8 nearly all HTML5 or Flash videos are only showing dark green instead of the image (the sound is fine).

    Metro IE litters my Start Screen with Favourites. I don't want them on my Start Screen!!!

  17. TheGame says:

    I noticed that in IE10 when closing or opening tabs sometimes there is a quick black flash. Doesn't happen in IE9. Also, sometimes the window frame gets inactive and then active after closing a tab, while other times the window stays inactive. Very annoying. This is in IE10 desktop (windowed mode) running on Windows 8 Release Preview. Hopefully this issues are addressed before final release.

  18. IE10 Fan says:

    Will IE10 support the HTML5 'hidden' attribute?

  19. Steve says:

    @pmbAustin – I read that article and I agree there is a usability issue there as IE seems to have issues knowing when it is in desktop mode or when it is in metro mode – and yes, Microsoft should fix that!

    However the general comments as to metro IE should support or should not support silverlight is a different issue.  Realistically we have to cut metro free from legacy plugins that would hold it back.  Silverlight should definitely not be part of metro IE – it does not belong on tablet devices and will never be included on an iPad, Android, PlayBook, Sony, or Kindle.

    For compatibility reasons, if Microsoft insists on full blown windows hiding in the background on a tablet (which I personally believe is a Major, Major, Mistake) then they will need to maintain 100% compatibility to desktop Windows 7 even though none of "regular" desktop windows belongs on a tablet.

    However back to point #1… yes, Microsoft should block all attempts to download and install any plugins in Metro IE… but needs to ensure that it provides a user friendly message (or politely, and successfully bump to desktop IE)  after which point, any attempt to click on 3rd party content, should bump to desktop IE.

    As you can already see… trying to please the tablet/touch market with the same OS as your desktop workstation is going to result in a lot of confusion and more importantly a lot of frustration… desktops will have metro mode that is only 1/2 baked… and tablets will have desktop mode (which ruins the tablet experience) and just highlights the tablets "slimmed down" UI as failures and omissions.

    I realize that Microsoft is banking on Windows 8 to try and stop the market bleeding to their competitors (lets face it, Microsoft has a massive uphill battle if they want to gain any tablet share) but this "mediocre hybrid" OS will only enable short term success… in order for Microsoft to succeed in the tablet space they have to sever the connection to desktop Windows in the next release (presuming legacy ISV's update their enterprise apps to metro)

    Its a stop gap measure – and it will hurt Microsoft's image a lot more than they are aware of.  If there is still time I would seriously consider killing the hybrid Windows 8 option before going to market.

  20. Steve says:

    oh and your comment form is still broken – please fix it.

  21. Tyler M says:

    Finished watching the MSFT presentation on the new surface.

    A few obvious questions.

    1.) finally MSFT learned about sexy – congrats it only took you 20 years!

    2.) ARM surface – will it too suffer ZERO comparability with existing (Today) apps? This is an absolute deal breaker if you do the hybrid OS instead of separating them

    3.) it's thin very thin this looks like a broken device just waiting to happen

    4.) pricing – way to be ambiguous

    5.) every single photo from the release shows Metro only – we take it this is due to how ugly desktop windows looks running on the tablets (at shows / demos we've seen in person so far) this is why the hybrid OS is a failure

    #StillNotInterestedInComprimise #Windows8 #TheElCaminoOS

  22. Xero says:

    @pmbAustin, yeah silverlight for web may be dying like flash, but SL as a multifaceted platform is not. The windows desktop, phone and metro apps are being developed in SL and its the primary platform for rich interface in the latest and future platforms from MSFT. Moreover, game development platform XNA also let the devs to include SL libraries.

  23. @Lewald says:

    Dude, you are using an older preview. Download and install the latest preview http://preview.windows.com .. 45-60 fps on IE 18-22 fps on Chrome.. Poor Chrome do sucks if u ask me! 🙂

  24. Real McCoy says:

    One of the most CRITICAL bug in IE8+ (excluding IE8).


    When the textarea is rendered in IE9, the undo and redo work unreliably. Same happens in rich text-editor. IE10 fixed this issue to 'some' extent. For example, using IE9 type some text in any MSDN-IEBLOG's post and press Ctrl+Z and then type more and press Ctrl+Y. Play with UNDO/REDO for some time with different scenarios. The try the same in IE10, FF, Chrome or any non-IE browser.


  25. Real McCoy says:

    BUT when the rich-text editor is rendered in a popup, forget about undo and redo, be it IE10 or IE9, it will break down and sabotages the whole experience. I will give you TWO examples (plus one for Windows Phone's IE9):

    1- CS-Cart (a business application: shopping cart solution)

    Download trial: http://www.cs-cart.com/trial.html OR register for online demo: cs-cart.com/personal-demo.html

    Once you are logged-in, open Administrative panel > hover on Design (top-right corner) > click on Template editor > Double click basic > double click admin > click on styles.css > click edit (at the bottom of the page).

    …and wait until the script loads completely. If the page freezes, recover the page and try again (that's what happened to me on IE10RP, Windows 8). Once the colored CSS code is displayed, try to scroll up/down and click on some code and try to edit it. You will see the reflection of text and some weird things happening like caret automagically changing its position once you press any arrow key or clicked somewhere on the code. There is NO way to edit the text successfully.

    Do the same in IE9 browser (in Windows 7). Then try it on FF, Chrome or any other non-IE browser.


  26. Real McCoy says:

    2- Windows Team Blog (windowsteamblog.com):

    Using IE9 browser (in Windows 7) with standard mode and IE10 RP (in Windows 8) with standard mode.

    Suppose me and Rodney are friends on Windows Team blog network. When I click on Rodney's name to see his profile page (windowsteamblog.com/…/rodneyej), under his picture, I see Start conversation link. Click on that link and the send-message popup will appear with rich-text-editor.

    Now, enter some text in subject and message. Click back and forth in Subject and message field. You will see the text-editor will stop getting focus.

    Then, try to send the message (click on start conversation) in IE9. Once the conversation is started click on Conversations on the top of the page and open the latest conversation you initiated. You will find out the message body is empty.

    To see more miracles, try to send same message using WindowsPhone IE9. (which is literally impossible!!).

    Speaking of Windows Phone IE9 and popups. I have an AT&T device. When I tap on Settings > About and tap the link under 'help contacts' (http://www.att.com/devicesupport), the page loads with a popup to select your device and there is NO way to successfully select the device and clear this step because everything in that popup is jagged, buttons unclickable and much more… If this is the situation with the device's carrier support homepage (the one present in phone's About screen), what should we expect from other RIAs? The same page works fine in iPhone, Android and even Symbian.

    There is lot of fuzziness when it comes to the behavior of IE with iframe-based rich-text editors and popups. Sometimes the layout is broken, sometimes the whole experience is cluttered, sometimes popup content is flickering/dancing with mouse/swipe movement, on WP sometimes popup is running away from you (you swipe down to see the popup and it will keeps running away downward) and since so forth. The text-editor developers still have to use 'hacks' to support even IE10. Compare it with FF and Chrome and having no-compromise approach, 'Nip the evil in the Bud' once forever!

    Thank you for listening.

    Bug report – connect.microsoft.com/…/problems-with-popups-iframe-based-rich-text-editors-cs-cart-windowsteamblog-etc

  27. Mitch 74 says:

    This comment system really sucks. Trying again.

    @Brian LePore: these optimizations have been useful in other browsers for years – and, as a matter of fact, you might get even better performances by using the COMPLETE form of parseInt: specify the radix too! Example, parseInt("10",10). You also have parseFloat.

    Do note however that using those for variable = parseInt("10",10) will force a copy by cloning + casting, and not a copy by affectation: myVal = document.getElementById('element').value allows you to change a DOM element's value without having to hunt for it through the DOM every time (note that this is in itself a form of optimization), myVal = parseInt(document.getElementById('element').value,10) won't allow you to do the same.

    Another optimization which is actually a good coding practice is to use strict operators: !==, === etc. since those require the elements compared to have the same type – it'll force you to use parseInt() and parseFloat. The only case where you might use the loose form ('==') is with typeof when not using ECMAscript5 strict mode, for backward compatibility with some really old browsers.

    In fact, one very efficient way to learn good JS coding is to pass your code through JSlint with as many checks activated as possible.

  28. PhistucK says:

    @Mitch 74 –

    "The only case where you might use the loose form ('==') is with typeof when not using ECMAscript5 strict mode, for backward compatibility with some really old browsers."

    Can you post a link or an explanation regarding this?

  29. Mitch 74 says:

    @Phistuck: I think (it goes back a loooong while) that IE4/IE5 (or was it 3?) didn't have the window.undefined property set by default, or that the typeof operator would return an object and not a string – it might have been in Opera 7, or something – I can't remember.

    It is however pretty much moot now, and you can actually make your code faster (but slightly less resilient to these very old browsers) by doing typeof yourvar === 'undefined' – that's on par with using parseInt(), parseFloat() and such. Please note that while not all browsers support more precise checks such as isArray(), several libraries (such as jQuery) flatten the field by making use of native implementations when present, or providing a JS optimized version.

  30. PhistucK says:

    @Mitch 74 –

    Oh, wow, Internet Explorer earlier than version 6 is… ancient history.

    Thank you for sharing. 🙂

Skip to main content