The race for speed part 4: The future for JavaScript

The race for speed - part 4

Browser vendors have ambitious plans for JavaScript. Many of them are making long-term investments in the web as an operating system. To get there they have set themselves the goal of running JavaScript code as fast as native C. If this performance can be achieved it will further blur the difference between native apps and web apps.

So how do you take a dynamic language and make it run anywhere close to native C?

ES.next
The next generation of the JavaScript language is currently being drafted. ES.next will be the sixth edition of ECMAScript, the specification from which JavaScript is derived, and is anticipated sometime later this year.

One of the stated goals of this project is fast compilation. A number of features are being discussed to achieve this including a type system, binary data and typed arrays. Typed data can be sent directly to a typed JIT resulting in much faster compilation and execution time.

Native browser support for ES.next is still poor but you can keep track of it with this ES6 compatibility table and even take it for a test drive with Google’s Traceur project – an ES.next to JavaScript compiler written in JavaScript. If you’re determined to use it now then take a look at the Six Project.

WebGL
JavaScript in the browser isn’t limited to DOM manipulation. The vast majority of modern browser games (those that aren’t using plug-ins) render directly to a single HTML5 Canvas element using the standard 2D Context. Canvas is essentially a big writable bitmap. Using JavaScript you layer, blit and animate other bitmaps onto it to create animation, games, graphs and so on.

The fastest way to render to Canvas is with WebGL – a JavaScript API providing hardware-accelerated graphics. This context greatly improves performance by offloading the computationally expensive process of rendering to the GPU, leaving the CPU free to manage the application logic.

Contrary to popular wisdom WebGL actually has some level of implementation in all modern desktop browsers. It is ready in both Chrome and Firefox but needs to be first enabled by the user in Safari and Opera. Microsoft has been the last holdout but references to WebGL have been found in leaked versions of their forthcoming IE11.

Unfortunately even with browser support you still can’t guarantee WebGL is going to work for all your users as they also must have up to date graphics drivers for their GPU. Google Chrome is currently the only browser to offer a fallback software renderer if those drivers do not exist. WebGL is a very powerful and promising technology but it’s not fully ready for primetime. Aside from some browser vendors security concerns, desktop support has some way to go and mobile support is very patchy indeed. And of course legacy browsers will have no support at all.

Javascript as a compile target
Although all modern web applications rely on Javascript for their client-side logic, not all of them are written in Javascript. Many are authored in completely different languages and then trans-compiled to JavaScript to run in the browser. Some of these, like CoffeeScript and TypeScript were created to make JavaScript development more robust; but others like Java, C++ and C# view JavaScript as just another compile target.

Cross-compilation is not without it’s problems though. Heavily minified output code is difficult to follow and debugging is only really practical in browsers with support for source maps – an intermediary file mapping the runtime Javascript back to it’s source language.

A couple of years ago Microsoft Engineer Scott Hanselman put forward the notion of Javascript as assembly language. His observation that modern minified JavaScript application code is unreadable is hard to dispute, but that post provoked a great deal of interesting debate. Many a web career began with a simple ‘view source’ but when that source is obfuscated are we at risk of losing new developers?

An interesting example of JavaScript as a compile target is Mozilla’s Emscripten project. This takes LLVM bitcode and compiles it to JavaScript. LLVM (Low Level Virtual Machine) is a very popular intermediary compiler format – you’ll find an LLVM compiler for almost any language. This kind of setup would enable you to write code in the language of your choice and then trans-compile it to JavaScript.

It’s still early days for this project but the team have already released some impressive demos. Developers from Epic ported the Unreal Engine 3 to JavaScript and WebGL using the Clang compiler to create LLVM from a native C codebase and then Emscripten to compile asm.js JavaScript from the LLVM.

asm.js
A companion project to Emscripten is asm.js. This takes the concept of JavaScript as machine code quite literally. The specification models assembly language using only a highly restricted subset of the JavaScript language. So although you could write asm.js by hand you really don’t want to. To get the best out of it you’ll need the help of two compilers.

The Emscripten compiler can emit asm.js. The resulting JavaScript maybe unreadable but it’s valid and backwardly compatible, meaning it’ll still run in any browser. The big speed boost comes when modern engines recognise the asm.js format and can push that code through a dedicated compiler. For this Mozilla are working on OdinMonkey, an asm.js-optimising compiler built on top of IonMonkey, and Google have also pledged to support it in Chrome.

Any JavaScript conforming to the specification negates the need for garbage collection, boxed values or dynamic types. Early tests show performance around half that of compiled C++; a phenomenal achievement and comparable to the speed of languages like Java or C#. The team even believe this can be improved upon.

Mozilla Research are really on fire at the moment. In addition to Emscripten and asm.js they also have LLJS (JavaScript as C) and are working with Intel on River Trail – ECMAScript extensions for multi-core parallel processing. With this much innovation happening it’s not hard to believe that JavaScript running at native speeds might actually be possible.

and finally… ORBX.js
One leftfield solution to the native performance problem is to sidestep it entirely through virtualisation. Instead of running an application on your machine you run it in the cloud and stream the results as video to your machine. This is the solution being put forward by Mozilla and Otoy with ORBX.js, a video codec capable of delivering 1080p entirely through JavaScript.

In the video above you’ll see 3D Studio Max running natively and in the browser via ORBX.js. While the technology is certainly impressive it may well create more problems than it solves. When everything is virtualised the bottlenecks become connectivity, latency and bandwidth, and any outage is fatal.

Whichever way it goes it seems that JavaScript has a very bright and interesting future.