 Hi everyone. My name is Corent Argodot. I'm a Compatibility Software Engineer at Human and I will be presenting how we migrated from JavaScript to Wasm and successfully deployed it in production. First, let me set the context. In this talk, I will talk about the differences that exist between running Wasm and running JavaScript, the differences that exist between compiling to Wasm and compiling to native platforms, and I will be giving some advice for your project based on our experience. However, I won't mention Wasm outside of the brother and I want you to keep in mind that what I will be presenting is not a magical recipe. It works in our case and is simply a feedback from our experience. But first, let me do a bit of history. LeMenn, formerly known as Center Ruling, is a technology company providing infrastructures and platforms for components. One of our products, CDN mesh delivery, leverages peer-to-peer technology to improve QoS and reduce CDN bandwidth in the video delivery pipelines of our clients. Originally, this product was web-based and thus written in JavaScript. It has later been integrated in an iOS and Android SDK without being rewritten. Back then, this decision was understandable, but it was not a viable long-term solution. This is why we decided to rewrite it from scratch. Talking about motivations, here are additional key points that convince us to migrate from JavaScript to C++ and target Wasm. First, we wanted to have a single code-based targeting the majority of platforms, including web. Then, we wanted to be able to fully exploit the hardware capabilities of native platforms. And finally, some of our algorithms were pretty complex and compute-intensive. For the rest of this talk, I want you to keep in mind the following assumptions. Our entire code base is written in C++, and we chose the Emscripten tool chain to target Wasm. We don't target only Wasm but also native platforms such as Android and iOS. Now that I did the introduction, let's dive more on the technical side. JavaScript and Wasm have pretty different paradigms, and here are the key differences between them. On one side, JavaScript is an interpreted high-level language, strongly asynchronous and internally based on an event loop. It's very popular and deeply integrated in modern browsers. On the other side, Wasm is presented as the web equivalent of native assembly language. Thus, it's very different from JavaScript. It's a very low-level language targeting a stack-based virtual machine. It's designed to be called from JavaScript in synchronous manner. These main differences have strong implications on how we should approach your code-based design. Concerning the differences between compiling to Wasm and compiling to native platforms, here are the key differences. Due to the way that most JavaScript engine work, Wasm is monothreaded and non-primitive. All codes to Wasm function are blocking and must return before letting any other JavaScript code to execute. On the contrary, native platforms can be monothreaded and are almost always primitive, meaning that threads of execution can stop in the middle of a function and continue execution later, letting time for other processes to run. As you can imagine, this will also have strong implications on how we should approach your code-based design. In case you are wondering, there are plans to make Wasm multithreaded, but we do not recommend using it now. It relies on web workers and shared web buffers that have been disabled in most modern browsers due to the recent spectrum and meltdown vulnerabilities. Also, there are libraries such as a Syncify integrated within EMScripten that lets you introduce asynchronous calls to JavaScript inside Wasm function, but be careful as it makes the output binary bigger, twice as big in our case, and also introduces a small overhead in terms of performance. Now that you have a clear understanding of the differences between our target platforms, I will be giving some advice that successfully helps us deploying Wasm in production. Let's start with the project architecture advice. In the case you have a modular design, you want to have a diagnostic interface and platform-specific implementations. That way, you won't have to be aware of the platform you're running on when working on the core part of your project. One way to achieve this is to leverage the power of your build system to automatically dispatch to the correct implementation, depending on the platform you are compiling to. Here is an example from our code base. This is the module that handles everything related to HTTP calls. As you can see, our Agnostic interface is as exposed headers in the include directory. We have the common code in the common directory, and you have one directory for the native platform, such as Android and iOS, and one directory for the web platform. When compiling to Wasm, our build system automatically selects the web folder to build sources. Now, on the code base general design, we suggest to design your common APIs with an asynchronous mindset. This may seem strange since Wasm calls are synchronous, but the stability resides in the fact that most interactions you will have with the browser and the JavaScript APIs will be asynchronous. You will be called back later with the result of what you asked for, but first, you need to return from the Wasm function. Designing your APIs around callbacks is a good way of achieving this goal. Please note that even if our native, these APIs behave in a synchronous manner, it's not really an issue in practice, and you want to adapt to the more constrained platform. Still, on the code base design aspect, we suggest you to take inspiration from the actor model to design the main module software project. In a nutshell, the actor model is a way of designing your code base around the idea that each module has its own state and communicates with other modules using messages. What made it really suited for our constraints is that it can easily be adapted to fully exploit the hardware capabilities of the various platforms we plan to target. In our case, we designed a task-based system that runs on schedulers. Each module has its own schedulers and schedule small tasks to get its work done. On Wasm, if you look at the context, you already have a scheduler for free, the one from your browser. Each scheduler of each module will be multiplexed on the browser scheduler and will run on the main event loop. The need for small tasks ensures that each module will have its time share and that we are not blocking the UI thread for too long. On Native, each scheduler will be able to run on its own thread, thus exploiting the full hardware capabilities of the platform. Furthermore, the actor model approach will limit common issues uncontrolled in multi-threaded programs such as data-race and shared states. Now, let's talk about debugging. If you have the possibility to do so, we strongly suggest you to do your debugging on native platforms. Even though debugging wasm on Chrome is possible if you build your project with debug flags, the support is still young, not variable, and rely on an extension to work properly. Furthermore, a lot of issues that your code base could contain can't happen in wasm due to the multi-threaded context. If you are interested in knowing how to debug on Chrome, I put a link to an interesting article on this slide. Finally, here is a small list of useful flags to use when compiling using EMCC, which is the EM script NC and C++ compiler. Dash Aussie to optimize for code size wasn't by any of the bad reputation of being bigger than their JavaScript equivalent, and that's true in practice. Dash Dash Profiling, this will keep the function names in the output binary and let you do profiling on Chrome using the DevTools. Dash Dash Memory Profiler, this will add an overlay to the page, giving very interesting information on memory fragmentation, biggest allocation set, and most frequent allocation sites. If memory footprint is a concern for you, this would be very helpful. And finally, Dash Dash Closure 1, this will enable the Closure compiler to optimize the JavaScript glue code generated by EM Scripting. In conclusion, I present a few key points that help us successfully deploy wasm in prediction, but this list is far from exhaustive. I simply kept the more important ones. Please keep in mind that wasm is still a very young target and thus moves really fast. EM Scripting documentation is not finalized and you will often have no other choice than finding the correct solution by trial and error. Also, EM Scripting offers a long list of flags and settings to help you during your development, and I put the link to the corresponding documentation on this slide. And finally, we created a repository containing all the boilerplate code needed to start a multi-part form project targeting wasm. If you have any questions on everything I just presented, don't hesitate to contact me on my email address on Twitter or directly on the repository I just linked before. Thank you for your attention and have a nice day.