JavaScript spin-off asm.js brings web even closer to native performance

JavaScript spin-off asm.js brings web even closer to native performance

Summary: Firefox creator Mozilla release benchmarks showing that asm.js, its performance-optimised subset of JavaScript, can deliver performance only 1.5x slower than code compiled to run natively.


JavaScript performance has come on in leaps and bounds in recent years but still lags some way behind code compiled to run natively as binary.

Firefox creator Mozilla claims to have narrowed the gap between JavaScript and native code performance through improvements to asm.js – delivering performance only 1.5 times slower than that of native.

asm.js is a subset of JavaScript that is optimised to maximise performance. asm.js is JavaScript and so will run in any browser but to get the best performance a browser's JavaScript engine needs to have been written to take advantage of the optimisations asm.js makes possible. Currently the only browser to support asm.js optimisations is Firefox, since Firefox 22, although Google has expressed interest in adding support to Chrome.

Mozilla's latest benchmark shows a significant improvement in the performance of asm.js over figures released earlier this year. At that point asm.js was delivering performance closer to 2x slower than native.

Mozilla achieved the performance increase by tweaking both Firefox's Spidermonkey JavaScript engine and the emscripten compiler, which generates asm.js code from C++. Unlike JavaScript the structure of asm.js is not easily readable by a human and asm.js is not designed to be written directly, but rather compiled from another language such as C or C++.

One change that led to "substantial speedups" in the performance of asm.js was introducing support in Firefox for carrying out floating-point operations using 32-bit floats rather than 64-bit doubles, which allowed Mozilla to add the float32 format to asm.js' type system.

Tests by Mozilla show Firefox with float32 optimisations can run benchmarks at around 1.5x slower than native. The red bars (firefox-f32) represent Firefox running on emscripten-generated code using float32. Run times are normalised to clang, so lower is better. Image: Mozilla

Mozilla points out of the peformance natively compiled code is not based on a single measure but a range, with different native compilers - in the case of this benchmark the C compilers clang and gcc - delivering code of differing performance.

"What this shows is that "native speed" is not a single number, but a range. It looks like asm.js on Firefox is very close to that range – that is, while it's on average slower than clang and gcc, the amount it is slower by is not far off from how much native compilers differ amongst themselves," Mozilla researcher Alon Zakai said in a blog post.

float32 code generation is off by default in the emscripten compiler, which Mozilla says is intentional as it can decrease performance when asm.js is run by JavaScript engines not supporting the Math.fround function (part of the proposed EcmaScript 6 specification). Mozilla hopes to enable float32 optimisations by default in emscripten in future.

While asm.js has Mozilla's backing, other major browser makers are looking to other technologies for improving the performance and/or maintainability of browser code, Google with NaCl and Dart, and Microsoft with TypeScript.

Zakai said there is plenty of scope to continue improving asm.js' performance.

"Even the current performance numbers – 1.5x slower than native, or better – are not the limit of what can be achieved, as there are still big improvements either under way or in planning, both in emscripten and in JavaScript engines," he said.

Topics: Web development, Enterprise Software


Nick Heath is chief reporter for TechRepublic UK. He writes about the technology that IT-decision makers need to know about, and the latest happenings in the European tech scene.

Kick off your day with ZDNet's daily email newsletter. It's the freshest tech news and opinion, served hot. Get it.


Log in or register to join the discussion
  • Why would anyone run a subset of Javascript?

    Javascript already teeters on the edge of being insufficiently powerful (though all the libs like angular and jquery make up for it.) Why would anyone want to reduce what it can do?

    I expect someone else will soon reach native code speeds without having to compromise.
    • It's not exactly limited.

      It doesn't really limit what JavaScript can do, it actually works like strict mode so asm.js only applies to the function or script it's used in, you can have it talk to normal JavaScript to gain the functionality you need.

      So you can get speed increases while still accessing everything JavaScript can do, you just have to abstract your code.

      It's how Epic Games ported the Unreal 3 Engine to JavaScript, they used asm.js for the tough stuff and regular JavaScript for the things asm.js can't handle (gaphics, sound, storage, etc).
  • Headline grabbing rubbish...

    A Javascript application will never be as fast as native code, not possible.
    Java has tried for years to get to the same performance as native code.

    I develop large applicationd in both Java and C++ and we have never been able to achieve the same performance in Java as C++. In fact we have spent so much time trying to do so that we have wasted this time.

    You can always try a make a single app be close to a native app but when you are developing a large suite applications you do not have the time to try make every individual component as fast as a native component it is not possible.

    It is just the Javascript people trying to grab headlines just like car companies do saying their cars can do 50mpg when in truth as the car owner you are never able to get the same figures!
    • This isn't just an attempt to improve performance of a single app

      asm.js is very different to vanilla JavaScript. asm.js code is limited to an extremely restricted subset of JavaScript that provides only strictly-typed integers, floats, arithmetic, function calls, and heap accesses. These limitations allows the JavaScript engine to make assumptions that optimise the performance of the code.
      John Resig produced an interesting write-up of the benefits and various applications of asm.js
      Nick Heath
    • Java isn't relevant to the discussion

      Java is a heavily run-timed platform running bytecode. Javascript's trajectory is increasingly one where browsers reduce the code to binary, and execute that. There's no reason, particularly with internal inferred typing, that Javascript should not get close to native speed.
      • Wrong! It is hard for general JS to approach native speed!

        There are lots of JavaScript programming constructs whose use presents difficulties for runtime systems to execute at native speed. Modern techniques like the one you mention can help a lot but there is likely to be an upper limit. Asm.js provides a target for languages, like C++, whose design was intended to allow one to code fast-running programs. One could instruct JavaScript programmers on how to avoid slow-running constructs and to code in ways that maximize performance but that would result in reducing JS to something a lot like asm.js!
    • ASM.JS is not for javascript developers

      As much as I applaud the efforts of asm.js, the fact remains that javascript developers (like myself) are not the target audience. In fact, it's more geared towards individuals like yourself using Java or C++ by allowing a cross compiled target native to the browser. This is not like an applet, or even Native Client, but a fully portable solution that lives and breathes and TALKS to the browser without using a stopgap like a Javascript shim.

      There's a great writeup by Steven Wittens, a fantastic pioneer in the web and javascript space here: that targets this exact issue. We should absolutely be excited about asm.js, but it's not geared towards people like me. The "javascript people" have almost zero benefit here-- you do. Put another way, asm.js allows developers like you to have damn near zero entry barrier to *relatively* fast code in a medium which allows for damn near zero entry barrier for your end user to manipulate. And it's getting better every day.

      Yes, you should be excited. I'll be excited when asm.js code can interface with DOM or extension level code with the same performance.
      Danny Garcia
  • Rust instead of Javascript

    Mozilla could use Rust in the browser, and then we could have a powerful language that would run as fast as C
  • Long time no reaction

    Been running textparsing code in such mode for quite a long time, and the performance is staggering. Especially mingw/QTwebkit cpu aligned compiles, running on Windows makes close to a practical joke of the publicly distibuted binaries packed by respective providers.
    The explicit cpu builds are even faster, but not portable so no distros there.
    Especially appearent on 100/100 lines and over with disabled disk cache.
    • Reply 2 myself hEh

      4 got to mention that C/C++ compiles both as most other hll's, are buit with asm mnemonics.
      So the relative enhancements in the js speed are due to lack of efficient mnemonics in
      the compilers used as the case with the primitive MSVC ones, or unability to apply the right set of switches on the builds.
  • some people here scream about JS not powerfull enough

    actually it's quite the opposite.
    those are the people that don't think about security.
    what about those viruses written in JS?
    JS is too powerfull.
    what do you want, for webpage to format your disk while you are away?
  • Not just performance reasons

    A key advantage to asm.js (and similar tools) is not just performance, but you get a wider selection of languages. In some domains this could make the difference between shipping on time and never shipping at all. For example, in graphics programming I've found JavaScript to be extremely painful for development, and would much rather use C++ -- it's surprisingly far more friendly in this area!

    I cover some of the problems in JavaScript in a recent posting of mine: