添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

How to build WebAssembly C# Apps with the Mono AOT and Windows Subsystem for Linux

Microsoft’s steady progress on WebAssembly gives an opportunity to test a lot of the new features regarding the payload size and performance balance.

Using the AOT provides a significant increase in performance over the mono interpreter, between 30x to 50x depending on the browser. This enables application such as the Uno Gallery or the Xaml Controls Gallery to run at very interesting performance.

Since the introduction of AOT , we noticed that the Wasm payload is particularly large. This is caused by multiple reasons, such as the fact that an LLVM backend is not used to generate WebAssembly or that some indirect calls are not supported by current Emscripten builds.

For those reasons, and a few others, the work that the Mono team is currently doing to support a mixed AOT/Interpreter Mode is going to play an important role to strike a good balance between payload size and performance.

At present time, the mono-wasm AOT tool chain is only compatible with Linux, and even though it will eventually support other platforms, it is required to setup a Linux machine or use the excellent Windows 10 Subsystem for Linux .

For those of you that have yet to experience WSL, Microsoft has added the ability for Windows to run native 64-Bits Linux binaries, untouched, non-virtualized. This means that most of the linux-compatible tooling, including mono, is able to run properly as if it were running on top of an actual Linux kernel.

We’re going to setup a WSL environment to build an Uno Platform application using Mono WebAssembly AOT.

Setting the build environment under WSL

Here’s what to do to, only once:

sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys    3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
echo "deb https://download.mono-project.com/repo/ubuntu stable-bionic main" | sudo tee /etc/apt/sources.list.d/mono-official-stable.list
sudo apt update
  • Install python, mono and msbuild
sudo apt install python mono-devel msbuild
wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
sudo add-apt-repository universe
sudo apt-get install apt-transport-https
sudo apt-get update
sudo apt-get install dotnet-sdk-2.2
  • Install ninja
sudo apt install libc6 ninja-build
  • Install emscripten 1.38.28, with a mono patch
cd ~
git clone https://github.com/juj/emsdk.git
cd emsdk
./emsdk install sdk-1.38.28-64bit
./emsdk activate sdk-1.38.28-64bit

Build an Uno Platform WebAssembly head app

For each shell you’re opening afterwards, you’ll have to do the following:

  • Activate emscripten:
source ~/emsdk/emsdk_env.sh
<WasmShellEnableAOT Condition="$([MSBuild]::IsOsUnixLike()) and '$(Configuration)'=='Release'">true</WasmShellEnableAOT>
  • Navigate to the Wasm folder of your application using the wslpath utility:
cd `wslpath "C:\Users\my_user\source\repos\MyApp\MyApp.Wasm"`
  • Build the application:
msbuild /r /p:Configuration=Release
  • Serve the resulting application
cd `wslpath "C:\Users\my_user\source\repos\MyApp\MyApp.Wasm\bin\Release\netstandard2.0\dist\"`
python3 server.py

You’ll notice that the mono.wasm is roughly between 20MB and 30MB, depending on the linker settings you've set , and using packages like Json.NET can significantly increase the binary size.

You’ll also probably notice that the build time can get pretty long, and the most time consuming step is Emscripten. This is known by the Mono team and will certainly be worked on in the future.

We’ll be discussing the use of the Mixed mode runtime in a next blog post, so we can get a performance/size balance for the generated binary.

Let us know what you think!

Jerome Laban has been programming since 1998, mainly involved in .NET and C# development as teacher, trainer, consultant in France. He is the CTO of Uno Platform, a framework trying to improve the development cycle of cross-platform apps using Windows, iOS, Android, and WebAssembly using Mono and Xamarin.
More posts by Jérôme Laban

Privacy Overview

This website uses cookies to improve your experience while you navigate through the website. Out of these, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may affect your browsing experience.

Any cookies that may not be particularly necessary for the website to function and is used specifically to collect user personal data via analytics, ads, other embedded contents are termed as non-necessary cookies. It is mandatory to procure user consent prior to running these cookies on your website.