Wednesday, September 27, 2017

Why asm.js?

Developing a JavaScript application in C/C++ may seem strange, but there are many languages that do compile, or transpile if you wish, into JavaScript. A large reason for this is simply the fact that JavaScript is a scripting language and was not really designed for large applications so simply does not have some of the language constructs that aid in the creation of larger projects. The later version of ECMAScript (the standard that JavaScript is based on) are attempting to solve that problem, with TypeScript being an example of what the future of JavaScript may be like. The problem, however, is that there are people using old browsers so may not have access to the latest language features. Therefore, tools such as TypeScript are useful as they take new language constructs and compile them into older JavaScript code making the code useful to a broader range of users.

Developing in C or C++ is quite a bit different from using a language like TypeScript that was designed to compile into JavaScript. The reason a person would do this would most likely be to port existing code to the web. In fact, Unreal and Unity are two examples of such uses of this process. In my case, developing in C++ makes some sense as it would give me a very performant version that would run on computers (and possibly Android, IOS however does not allow emulation). The web version would be compiled into asm.js to give it satisfactory performance on browsers that implement asm.js and would still run on browsers that did not support asm.js.

The last sentence may sound contradictory but only if you don’t know what asm.js is. For those of you not sure what I am talking about, asm.js is a subset of JavaScript that can be compiled into very optimized machine language. Browsers that support the standard will then spot the asm.js code and compile it into native machine language for the best speed. Because the subset is designed for optimal code, the result is much faster execution than what JIT compilation would give you. Browsers that are not aware of asm.js would just see perfectly valid JavaScript which it would be able to run, though this would be at JIT speeds so the results would not be as good.

There are a couple of other ways of compiling C++ for use on a web page. The most obvious alternative is Native Client (NaCl) which is Google’s sandboxing technology for allowing native code to run in a browser. This has the advantage that the code being run is already compiled, but needs to be compiled for the processor that the client is using (so multiple versions would need to be created). The bigger issue is that many browser venders are not implementing this so it largely limited to the Chrome browser.


The other alternative is the relatively new WebAssembly bytecode standard. Instead of using a subset of JavaScript, this uses a bytecode compiled version of JavaScript. This results in much more efficient downloading of the application as the bytecode version is smaller than the code version. I find this a fascinating development as what is effectively happening is a replacement of Java bytecode that is vanishing from browsers and replacing it with a new bytecode. It is receiving support from all the major browser vendors but is a relatively new standard. In the future, I may go with WebAssembly for creating web applications, but as it may be a while before older browsers that can’t run it disappear, going with asm.js in the short term makes the most sense. Once I start getting some asm.js material out, I will see how difficult it would be to support both formats.

No comments:

Post a Comment