Webassembly can’t access the DOM. What?
What is the DOM? I am sure Webassembly is going to bring developers from areas where the DOM concept is not familiar, like myself. This post explains what I have learned about the DOM and it contains a small Webassembly program that is going to change the content of a HTML document.
DOM stands for Document Object Model, there is an official DOM definition given by W3, you can check it out, I am sure it is correct, well, it must be, they define what it is!
That is a little too deep for a first look into it. It is like having to study molecular biology when you want to decide what yogurt to buy…
OK I will stop here, no wait, there is also two other important facts, the DOM is unrelated with any language, and it belongs to the browser.
Before writing this article, I had promise myself to keep the definition in one paragraph, and I failed…
Why Webassembly Can’t Access the DOM?
With that in hand, lets do something Webassembly.
Using Webassembly to Change a Button Value
A button value is part of the DOM. In the following example we create an HTML document that defines a button with a default message (“click here to see wasm changing this message”), and we will have a Webassembly function that will change that value. The new value will show how many times the user have clicked the button. The variable that keeps this count is defined inside the Webassembly module. We also explain how EMSCRIPTEN makes it easy to do all of this.
Following is the HTML code (content of dom.html file), very simple, it basically defines a button, loads a Webassembly module and executes the Webassembly function IncrementClickCountOnValue() when the button is clicked.
The following C code (content of dom.c), only has one function, it uses the EM_ASM_ interface macro. Take a look at the comments in the code for detailed explanations.
emcc dom.c -O1 -s MODULARIZE=1 -s WASM=1 -o dom.js
This compilation line takes the dom.c file and generates these two files:
- dom.wasm contains the wasm module.
A note about optimization. I generally use -O1 because it allows a human to look at the generated code, -Oz makes it difficult. Comparison between optimization option and file sizes:
|dom.js||66,535 bytes||16,916 bytes||74 % reduction|
|dom.wasm||10,182 bytes||221 bytes||98 % reduction|
To run the code, just start emrun to serve our page and point your browser to: http://localhost:8080/dom.html
emrun --no_browser --port 8080 .
It was surprisingly easy to modify the DOM from within Webassembly, EMSCRIPTEN does all the work for us. This is an area that is going to change a lot in the future, so it might be wise to concentrate all the code that deals with the DOM in one file because when accessing the DOM from Webassembly becomes standard, it would be easy to port from EMSCRIPTEN macros into the new method.Leave a message below. Webassembly is evolving rapidly, please let me know if this post got outdated.