001 — WebAssembly and JavaScript : The Introduction.

Michael V.
9 min readJun 27, 2021

Web Assembly is a low-level language meant to be fast, secure and reliable. Today most Browser vendors can run Web Assembly at an incredible speed. C/C++ can compile to a WASM file then you can run the code on the browser near-native speed. We can take existing C/C++ code and run it on the web. For instance, OpenCV is a C++ library targeting real-time computer vision. It is available on the browser, and the speed at which it is running is affordable for web users. Unreal Engine, Adobe Acrobat, written languages created by C like languages can compile to WASM files and run in Chrome, Firefox, Safari, etc.

Many other languages can target WASM files, languages like Rust, Golang, Oxygen, etc. WASM is augmenting every day also the number of tools, features and compatibility spectrum available.

WASM is hardware Independent, platform-independent, portable, modular, fast, safe, compact, efficient, and many other features. It is not the perfect low-level language though it does great.

To understand how it works, let’s write some code using WAT files. WAT stands for Web Assembly Text Format. WAT files are the way that we can create WASM Modules using WASM syntax, tokens and grammar rules. WAT Files are like JS files or C files and CPP files that would target compilation to a WASM file. WASM files are in binary format, a text representation of binary numbers, a language the machine can understand easily.

We would create the smallest WASM module that we can compile and import on JavaScript.

The Smallest WASM Module

Know we need to compile the WAT file to a WASM file. I am compiling WAT to WASM files using a tool called wat2wasm provided by the WABT project, which is available for free on GitHub. The only constraint is that you need to compile these tools by yourself, though the instructions to make the compilation are on the website.

Let us create the code that can import this module into the HTML file using JS. For this task, we need to use WebAssembly API. All major browsers include WASM API.

Let us break it up:

  • Line 20. loads the file. A file is a series of bytes and nothing else.
  • Line 21. loads the bytes as a buffer. A buffer still a series of bytes, but it is how JavaScript can read them.
  • Line 22. Instantiates the module and save it in a variable.
  • From Line 26 to 31. It is running an IIFE, which is a function immediately invoked. We are saving the module in an external local variable and logging it.

Let’s run a Web Server on the folder where these files are stored. In this case, I am using Live Server Extension on VS Code to make it simple.

Open up Chrome, go open Developer Tools and then to the console tab. Inspect the returned object of the module instance, take your time to familiarize yourself with all of the available properties, but especially with the exports member. It is empty; No properties, but we can add things like functions, memory buffers, tables, etc.

WASM and JS are interoperable. They can share functions, memory, variables and objects that we will study later. But for now, let us start passing the simple JavaScript Log Function to web assembly and use it within the WASM module.

To achieve passing a function from JS to WASM. First, we need to create the JS function, put it in a JS object and then import this variable into the WASM module.

Notice we added the imports variable to the “loadWASM ” function in the second parameter.

Inside the WASM module, that is the WAT file. We need to import the JS function, declare its signature and then call the imported function where needed.

Let us keep writing code on the WAT file. We need to create a function, choose a name, and state that we want to print the parameter that it is taking.

Include the code to export the function to JS. Notice that variables in the WAT file start with the dollar sign but exported or imported elements from JS are in double-quotes.

Compile the WAT file:

Now, go to Chrome again, console tab, inspect the WASM Object and call the function as many times as you want.

We will study in more detail WASM instructions and grammar. But for now, try to master how to import and export between JS and WASM.

If you want to practice online and download your WASM files, go to the following links. I recommend you WASM Studio.

https://webassembly.github.io/wabt/demo/wat2wasm/

https://wasdk.github.io/WasmFiddle/

https://webassembly.studio/

I want to show you something interesting that demonstrates the difference in speed between JS and WASM. We will create a function in C language, compile it to a WASM file using the EMCC tool. This tool can provide you with a JS file that automatically loads the WASM file and put the module in a JS Variable Named Module. This Module Object contains all the exported functions. It is a demonstration that shows us the difference in speed of using JS vs WASM functions. At another time, I will explain to you the details of the code.

Let us start creating a loop in a WAT file to print 100000 numbers. Know made a C file, compile it to WASM with EMCC and load the generated JS file to the HTML page. Finally, we will call both exported function to print the 100000 numbers. The difference in speed is colossal, around eight times faster on my computer. Probably this is because the JS Log Function feeds new lines on every number logged to the console. But I do not want to break lines for each log when logging thousands of numbers. With JS Log Function in the Browser is impossible to print number without putting newlines unless we do some tricky stuff and write more lines of code to make it possible.

Let us continue testing performance. We will create two modules; one from C language using only C functions to print numbers and a second module from a WAT file that will use JS Log Function to print numbers.

We would start with a C file for our first module.

Now we would compile it using EMCC that provides a JS file and the WASM file.

Import the JS file in the HTML.

Remember, the generated JS file contains a variable named Module which includes the exported variables. Know open Chrome, go to the console tab and run the function. EMCC will rename this function as _logManyNumbers adding an underscore at the beginning of the name. EMCC additionally has added many more properties to the Module object.

I will explain this when we get involved entirely in how EMCC works. At the moment, let us execute the exported function. I am sure that you will sense that it finishes immediately when it executes on the console.

It is time to do the same using the JS Log Function. First of all, let us create the WAT module, import the log function and log 100000 numbers.

Do not be afraid of this code. Commonly, we will not write code using WAT files, but small programs are affordable. It is worth spending some time trying to understand what is going on. I will explain in the future some of the features. Know our next step is to compile the WAT file.

Load it on the HTML. Do not forget to pass the imports from JS to the lodaWASM function.

And execute the exported function was stored in the module variable. You will need to wait some time for this function to complete since it is slower.

It is time to compare performance. The following way is not a robust one to test performance but can give us an idea to understand the breach in performance between JS and the C language. Though, we have JS, C/C++, and the Browsers, all in the same place creating new ways to solve problems.

To begin our test, we need to create a function capable of measuring the execution time among different functions. I will share what had come to my mind.

Write the code at the beginning or end of the script tag in the HTML file. Go to Chrome, console tab and test our functions.

It is unbelievable. WASM is around ten times faster to print all those numbers on my computer. I want to share one more test with you. Create a function to print 100000 numbers using only JS code.

Run the test.

WASM module from the C file is the winner. It is super fast logging numbers to the console. Also, It is interesting that JS code beats the WASM module that comes from the WAT file. Unfortunately, I do not know why it happens, though I have an idea. But, WASM is undoubtedly faster than JS in more complex examples, especially in processing 2D or 3D graphics, AI, and math calculations.

Why is the WASM module from the C file around ten times faster than the others two? To answer this, take a look at the C file from before. Notice that it only breaks one line. It is after processing and printing all the numbers. JS cannot do it with its native Log Function. It breaks lines on every log making it slower. But C language includes a powerful function available in other languages like Python, Java, Julia, etc. That can do it. It is the printf function. This tool and many more are available in JS thanks to WebAssembly, Chrome and tools like EMCC and hundreds of people working on this technology.

Know, we have the power of JS and WASM bytecode available in the same environment. We have the capability of C/C++ and other languages in JS, the combination is incredible.

If you want to download all the files and play around with them, you can get all of them from my GitHub account. They will be ready to run on your computer. Do not forget to create a web server that points to the folder that contains the files.

If you have liked this content, leave many applauses that will increase my motivation to keep writing. Thank you for reading.

--

--