Do you need a WebAssembly tutorial?
Get to know WebAssembly in under 15 minutes with this tutorial!
I’ll explain how easy it is to get started with WebAssembly.
Let’s get started!
What is WebAssembly?
“WebAssembly” is a new way to execute bytecode in the browser in a secure and portable way. Bytecode is superior to JavaScript in terms of performance. Programme types such as video editing, games or CAD are possible and very performant with WebAssembly.
Programming languages such as Java, JavaScript or Python use an intermediate step to compile the code. This makes execution slower.
Java uses the Java byte code before the software is translated into machine language. This step increases the portability of the software, but slows down the execution.
New possibilities with WebAssembly?
WebAssembly is the first standard that enables computationally intensive applications in the browser. WebAssembly allows online games and video editing to flourish. A video editing program can export the film close to the machine and with multithreading.
WebAssembly has been standardised for all major browser engines since 2017. The W3C consortium is working on improving WebAssembly to enable even greater speed in new generations.
WebAssembly examples
WebAssembly is not just a theoretical wish, but some developers have used WebAssembly in various projects:
A collection of WebAssembly projects:
- Try this online video encoder to convert a video to a new format. You don’t have to install any new software, but can convert videos right away by loading the website and using your local computing power.
- Fancy a bit of gaming? You can run an entire 3D game with “fancy” graphics and sound on your computer in a few seconds without downloading hundreds of gigabytes of data.
- Mozilla hosts a first-person shooter that demonstrates what is possible with WebAssembly
- Got an image that’s too big? Use the resizer to reduce the size of your images. Choose one of the modern (lossless) compressions to optimise the file size:
Why is WebAssembly faster than JavaScript?
Loading time: Wasm files have a small file size because they are written in machine code. The smaller file size reduces the loading time of WebAssembly, which improves the loading performance of the entire website.
Execution time: The execution time of Wasm corresponds to the native execution time of machine code -20% for the encapsulations (security). WebAssembly takes into account that the created machine code is executed safely. The overhead reduces performance by 20%. A parser must first parse JavaScript, then a compiler checks whether a routine can still optimise the generated machine code (TurboFan).
Multithreading: JavaScript needs 1 core to execute the code. Your computer can only execute 1 statement at a time. In contrast to JavaScript, you can utilise the full power of multithreading with wasm.
When is WebAssembly a good choice?
WebAssembly is not a miracle cure and not the best replacement for JavaScript. WebAssembly is not 100% optimised to modify HTML Document Object Model (DOM). The application focus of Wasm is on demanding and computationally intensive tasks, such as image manipulation and generation.
JavaScript is required to call Wasm functions. JavaScript should make simple changes to the user interfacebecause the programming language was originally designed for this application.
Tutorial WebAssembly
- Install the Emsscipten SDK.
- Create C code with a few special features so that you can reuse them later in WebAssembly.
- Compile the C code into the Wasm format via the Emsscript SDK.
- Create the HTML framework with a JavaScript function that calls the Wasm format.
- Use a JavaScript function call that calls the machine code.
WebAssembly IDE
The WebAssemby.studio is suitable for testing and trying things out
You can configure and compile a Hello World template on this website. You don’t have to set anything up and can start programming straight away. You can use the online IDE to write C code, compile it and display it on the website.
This tutorial extends the Hello World project with a little more code.
Your C project in the browser
1. Create a Hello World template at https://webAssembly.studio
2. Change the programming code:
In the Main.c
#include
#include
#include
#define WASM_EXPORT __attribute__((visibility("default")))
/* WASM_EXPORT is the marker for JavaScript so that it can find the function again */
WASM_EXPORT
int powerer(int a, int b) {
/*You can use the full power of C in the functions */
return pow(a,b);
}
/* Another function for a JavaScript call */
WASM_EXPORT
int squareroot(int a) {
return sqrt(a);
}
/* function to be found in JavaScript*/
external void putc_js(char c);
/* WASM call - please do not change */
WASM_EXPORT
size_t writev_c(int fd, const struct iovec *iov, int iovcnt) {
size_t cnt = 0;
for (int i = 0; i < iovcnt; i ) {
for (int j = 0; j < iov[i].iov_len; j ) {
putc_js(((char *)iov[i].iov_base)[j]);
}
cnt = iov[i].iov_len;
}
return cnt;
}
JavaScript:
let x = '../out/main.wasm';
let instance = null;
let memoryStates = new WeakMap();
function syscall(instance, n, args) {
switch (n) {
default:
// console.log("Syscall " n " NYI.");
break;
case /* brk */ 45: return 0;
case /* writev */ 146:
return instance.exports.writev_c(args[0], args[1], args[2]);
case /* mmap2 */ 192:
debugger;
const memory = instance.exports.memory;
let memoryState = memoryStates.get(instance);
const requested = args[1];
if (!memoryState) {
memoryState = {
object: memory,
currentPosition: memory.buffer.byteLength,
};
memoryStates.set(instance, memoryState);
}
let cur = memoryState.currentPosition;
if (cur requested > memory.buffer.byteLength) {
const need = Math.ceil((cur requested - memory.buffer.byteLength) / 65536);
memory.grow(need);
}
memoryState.currentPosition = requested;
return cur;
}
}
let s = "";
fetch(x).then(response =>
response.arrayBuffer()
).then(bytes =>
WebAssembly.instantiate(bytes, {
env: {
__syscall0: function __syscall0(n) { return syscall(instance, n, []); },
__syscall1: function __syscall1(n, a) { return syscall(instance, n, [a]); },
__syscall2: function __syscall2(n, a, b) { return syscall(instance, n, [a, b]); },
__syscall3: function __syscall3(n, a, b, c) { return syscall(instance, n, [a, b, c]); },
__syscall4: function __syscall4(n, a, b, c, d) { return syscall(instance, n, [a, b, c, d]); },
__syscall5: function __syscall5(n, a, b, c, d, e) { return syscall(instance, n, [a, b, c, d, e]); },
__syscall6: function __syscall6(n, a, b, c, d, e, f) { return syscall(instance, n, [a, b, c, d, e, f]); },
putc_js: function (c) {
c = String.fromCharCode(c);
if (c == "\n") {
console.log(s);
s = "";
} else {
s = c;
}
}
}
})
).then(results => {
instance = results.instance;
/* Here the call is made from JavaScript into the C code*/
document.getElementById("container").textContent = instance.exports.powerer(3,4);
}).catch(console.error);
3. Run the code
4. And see the output (here for the Hello World project):
Alternatives for WebAssembly
The best known alternative for WebAssembly is JavaScript. JavaScript is slow, but almost every browser understands this type of programming.
TypeScript, Vue.js or JQuery are other alternatives. The developer has a different development experience, but the product is the same because a build script compiles them all to JavaScript.
TypeScript is the better JavaScript. Typing, functions and classes enable Java-like programming. The typing helps you with orientation and the class structure creates an overview in the project.