So, I'm gonna be honest with you folks. I do a terrible job of staying up to date on the latest tech. I see things come up on Twitter, I see people talk about it, I add it to my list of things tto learn, and then I never get around to it. It's a vicious cycle. But, it's a new year, so it's the perfect time to break vicious cycles.
Earlier today, I saw a tweet about WebAssembly. I've heard a lot of chatter about WebAssembly over the past couple of years. I've skimmed through the WebAssembly website and even attended a talk on WebAssembly at a conference once. That being said, I've never really taken the time to dive into the technology and really understand what all the enthusiasm was about. Until today. So, why the heck is everyone talking about WebAssembly?
What?
Answering "What?" is usually a good place to start when trying to figure out anything new. The WebAssembly homepage provides this description:
WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable target for compilation of high-level languages like C/C++/Rust, enabling deployment on the web for client and server applications.
This description was definitely not written for people who wanted to learn about WebAssembly in a hurry. I did some snooping around to see if I could find an explainer article that was a little bit more approach. I recall that Lin Clark produced some pretty good content on WebAssmebly so I decided to see if her introductory article would be a little bit more helpful.
I found that her intro was pretty useful. It confirmed that my assumption on what WebAssmebly was was true. WebAssembly is a way to take code in any programming language and run it within a web browser. OK. That's a much more approachable definition and I can immediately see the value of a technology like that. Now, how does it work?
How?
While the "What?" is an interesting question to answer, the "How?" is even more interesting. Anyone who knows me (or has read my previous blog posts) knows that I like to get very nitty gritty when exploring how things work. I figured that for this, I'd start by writing my own program, compiling it down to WebAssembly, and then running it in the browser.
I found that WebAssembly's introductry documentation was a lot more approachable than some of the text on their landing page. I followed the directions under the "Downloading the Toolchain" section. They instructed me to clone the Emscripten SDK and install it on my local machine.
$ git clone https://github.com/juj/emsdk.git
$ cd emsdk
$ ./emsdk install latest
$ ./emsdk activate latest
$ source ./emsdk_env.sh
Much to my surprise, absolutely nothing terrible happened as I ran these steps. That's right. Nothing went wrong when getting set up for something new! What a pleasant surprise.
The next step was to write a "Hello, World!" program in C and compile it to WebAssembly. Once again, the steps under the "Compile and run a simple program" section of the Developer Guide.
So, what essential happened. I wrote a program in C and compiled that program using the Emscripten toolchain. This Emscripten compiler generated a Wasm source file, a JavaScript file, and an HTML file. The HTML page loads the JavaScript file which in turns loads the Wasm source file onto the page. Since I'm using a recent version of Chrome browser, the compiled Webassembly in the Wasm source file is run by the browser.
The WebAssembly program is represented as a plain JavaScript object, aptly called Module
in the codebase. This Module
object is generated in the javaScript file generated by the Emscripten compiler and stores information about the memory used within a WebAssembly program, the Wasm binary associated with the program, code to manage the runtime status of a program, and more. Essentially, this module encompasses the data and code of a WebAssembly program and can be sent to wherever you need a WebAssembly program to run (like my browser). You can find more information about WebAssembly modules in this design doc.
Why?
Now, why WebAssembly? One of the most popular reasons that came up when researching this question was WebAssembly's speed.
Although performance is an important factor for any technology, I don't believe it's the most important factor. I've seen far too many developers sacrafice other important factors (like developer experience and maintainability) at the altar of performance when it wasn't necessary.
To clarify: I'm not dismissing the benefits of WebAssembly's speed in certain contexts. I'm just looking for more pros.
What else does WebAssembly offer? Well, the other obvious big perk is that it expands the types of programs (and by extension programmers) who can deliver their applications through the Web. I can't understate the value of this. It's an interesting premise. I'm curious to see how this will change how people develop on the Web and what impact WebAssembly
The reasons above are compelling for WebAssembly as a technology in general, but I'm curious to know if I might be able to use it directly in the contexts I'm working in. I spend most of my time these days doing full-stack web development with React in the front-end and Node in the backend. I found one rather compelling and interesting use case for someone like me.
From the "How?" section above, you'll recall that WebAssembly runs compiled code within the browser. Because this code is compiled, it has undergone a certain amount of obfuscation.
Despite these, there are still ways to get around this obfuscation. When I was researching this, I came across this paper that discussed ways that compiled WebAssembly modules could be deciphered. When there's a will, there's a way.
Why not?
No technology is perfect. After exploring some of the reasons for WebAssembly, I decided to see if there was any reasons to avoid WebAssembly. What are the shortcomings of WebAssembly?
This was a surprisingly difficult question to answer. I suspect that because WebAssembly is a fairly new technology, it hasn't achieved the criticial mass necessary to spot any bumps or kinks in the technology. Or maybe WebAssembly is flawless and perfect and has absolutely no flaws?
I will say, it would've been a little easier to find reasons not to use WebAssembly before major browsers adopted the technology by default. The fact that Firefox, Chrome, Edge, and Safari all support WebAssembly. All that being said, here's a couple of the things that I've noticed while researching Web assembly.
From the "How" section above, you might recall that the C source code that I wrote was eventually converted to a Wasm binary that was loaded onto the webpage and executed by my browser. There's a whole new asset (the Wasm binary) that needs to be sent down the network to my browser. As with anything that is sent down via the Internet to user's browsers, care needs to be taken to minimize the size of the binary so that it doesn't slow down page load times. This isn't a downside of WebAssembly, per se, just something to watch out for. It's not like this problem doesn't exist with non-Wasm assets on the web. And from my research, it seems like quite a few people have written articles on how to minimize the size of these binaries so shrug, this might not actually be that big a deal.
Another cumbersome issue that I came across when researching WebAssembly is the interpolarity between WebAssembly and JavaScript. For example, how do you invoke a function written in JavaScript from your WebAssembly program (in whatever language it is written in)? I found a Medium article that discussed a work around one developer used and a proposal for allowing the WebAssembly modules that I described in the "How?" section above to be imported like ES6 mdoules.
So yeah, I guess, for the most part the "Why not" for WebAssembly is that it's a fairly new technology and not all the details have been figured out. But from what I read, the champions of the community seemed pretty proactive about responding to issues and creating design proposals for problems so there's that.
Conclusion
Alright! That was a pretty fun exploration. I'm glad that I'm a little bit more confidently informed on what WebAssmebly is. I don't imagine myself using it any time soon, but I think that's because I'm not working in a situation (building 3D games, etc) that would benefit from using WebAssmebly.
Are you currently using WebAssembly? Do you have concrete plans to use it in a feature/product you'll be shipping soon? Did I misunderstand anything about WebAssembly in this blog post?
Top comments (33)
I think WebAssembly will have more value for developers who aren't using Javascript for the back-end. Like, um, me. As a C# developer, being able to re-use C# code client side will have a significant impact on how I work. I can't wait until Blazor is mature enough to be used.
I see. Do you know which parts of your codebase you'd compile to WebAssembly assuming all the tooling and such is mature?
I'm a member of the strongly-typed church. I prefer to catch errors at build time instead of runtime. And one of the things I like about C# and Visual Studio (not VS Code, actual VS) is being able to easily rename properties or methods and have that change automatically done through the entire codebase. It's also nice to be able to quickly and easily see what code is referring to what and where.
This breaks down at the Javascript/C# barrier. As one example, when I'm dealing with json responses to ajax requests, I usually create a class in C# for containing the data which then gets serialized into json. I then have to very wary of changing that class because it could then break the javascript that consumes it. And identifying what may be using that json in the javascript code can be a challenge.
Typescript would help with this but brings some of it's own challenges. WebAssembly would remove the C#/Javascript barrier and let me use C# on both sides. To more specifically answer your question, at a minimum, some of the Javascript code that I would convert to C# would be the code that handles the json responses from the server since I could then have that code use the exact same class used by the server.
Hi Tim, you might want to look into a validator for your JSON. I've never used any of them but you can find some here
WebAssembly, at least for now, it's not going to help much in that, unless you write the entire app in C# with WebAssembly. The thing is that JS and WASM need to continuosly serialize and deserialize data coming from one to the other back and forth. So, if you write the JSON parser/validator in C# it would mean that each time you have to go from JavaScript (used to issue the HTTP call) to C# (to parse and validate the data) to JS (to use such data). That part of WebAssembly is still quite slow.
There a few proposals around to help with that but I think WebAssembly will truly excel for CPU heavy computations or when a lot of concurrency is involved (because they are adding threads to it).
I would use HttpClient in Blazor. But I agree that the interop between Javascript and C# could become an issue.
Thanks for this post. This is the most straightforward article I've read about Web Assembly.
I think people haven't really started playing with because it involves the browser but it's supposed to be used for tasks that are typically run in the back end. We haven't yet broken through that mentality of having things happen where we expect them to.
Nailed it, it requires a (big) shift in mentality.
Some are still trying to understand how to use web workers effectively or edge computing.
By adding WebAssembly (which is getting multi threading) to the mix we'll be able to efficiently run web apps using the CPU of the client instead of running jobs on the server and then delivering the result to the client.
There are technologies now that allow develoeprs to write
TypeScript
and compile it to Web Assembly. The technology is calledAssemblyScript
.I have written an article about it here.
Also, I'm really glad to see Web Assembly catching so much interest! It's going to make a lot of waves in the Web Development community for years to come.
One of the big downside of the current node/npm ecosystem is maintainability.
Don't touch at a frontend SPA project for 6 months and I dare you to be able to make it build again.
Even if you have a package lock file, it will just not build nor run anymore.
Same thing about upgrading, there is no elegant way to upgrade the dependencies without breaking everything.
The lack of a really standard library like you could find in Golang gave place to thousands of "< 100 lines of code" libraries of very heterogeneous quality.
Even a quite small frontend project ends up with a thousand dependencies with almost the same amount of different authors and with NPM telling you some of them have critical security.
Golang or C++ project I wrote 3 years ago still compile and run as intended.
If I can write a web app in Go, using something like Vugu (vugu.org), I won't hesitate for a second.
I don't foresee myself using WebAssembly so much as using things that make use of WebAssembly. I've been tracking WebAssembly for a while as reason to keep leaning in on the browser as a platform.
Support for WebAssembly is surprisingly far along:
Yeah. This was one of the things that impressed me too. Multiple browser engines hopping in to support the technology this early in seems like a really good sign.
One interesting case I've read into a bit, but I'll admit I've stayed pretty surface level with is Dropbox developing client-side compression which would be fairly infeasible with JavaScript:
blogs.dropbox.com/tech/2018/06/bui...
It pushes client-side computing way further than ever possible before in the browser.
Client-side compression is a great use case, I didn't even think about that.
If a user wants to take a photo on their phone and post it to a website, they'll upload it in the default maximum resolution and then the server will have to compress it. With wasm the resizing could be done in browser and save bandwidth/data plus server resources.
I like Web Assembly due to it allows ppl to use different languages for Web development and the only company that I know of that has fully adopted it is Figma.
Which I'm one of the developer in my company that uses that design tool in a web browser on Linux machine.
Actually pretty no one is talking about WebAssembly, compared to Blockchain or IoT is still an obscure technology.
Like PWA they need a wide adoption first, and to solve a business need.
It's possible that there is a decent amount of "talk" in terms of podcasts, conference talks, etc. But Google trends probably is more reflective of what problems people are solving on a day-to-day basis. I doubt Webassembly is ever going to be the actual concern of that many developers, even if it gains popularity. But idk.
I think blockchain is a huge outlier in its capacity to gain mainstream traction. Even when Webassembly is well-established, I doubt the news will report on it.
There is support for direct C++ to JavaScript function calls using something called "embind" (feature of the emsdk). At work we use I to wrap our C++ API in a js-friendly API. So fast & easy compared to how it used to work where you could only communicate with JSON.stringify or synchronizing state with SharedArrayBuffer.
I think embind might be experimental. At work we have not used it with production code but I can't wait until we do.
It's kind of that idea of a universal binary. If your computer can run a browser, it can run a WASM binary file. The coolest part is that it can be distributed just by visiting a website. I think getting webapps even closer to performance parity with native apps is still the goal. Allowing any language to compile to WASM is kind of a nice side-effect of having it running in a browser-based virtual machine.
Great article! I have been keeping up on the general development of Web Assembly ever since it was asm.js and it's really cool to think that soon you could write your software once and have it run on every platform that has a browser. Also if you interested this talk from 2014 is great...
[destroyallsoftware.com/talks/the-b...]