BUT, putting Mono out there let everyone else in the community start developing tooling (that Microsoft will take the best ideas from before politely acting like the community didn't keep the whole idea afloat.)
For context, the Blazor team started with their own interpreter compiled to WASM (via emscripten) instead of using either Mono or CoreRT - because shipping and getting user feedback is really important, and you can't do that while waiting for the ideal tech to be ready. It was swapped out later.
CoreRT is pretty cool tech but I rarely encounter anyone using it. Hopefully that will change in the future. The only CoreRT-based production app I know of is Streets of Rage 4 and it's a very recent release.
I agree that getting early user feedback is really important, but IMO it would be better if a limited version of Blazor WebAssembly (that would support only subset of .NET features, but have usable runtime size) was released on CoreRT tech and then slowly add more features. Blazor WebAssembly at it's current state, even though it supports all features, is too big to be really usable.
Spreading development resources thin between old tech like Mono and future tech just means future tech will be delayed even more. And when they figure out that in order to get the size down to a competitive levels, it would be better, if some features were kept out of the WebAssembly runtime (eg dropping reflection and relying on code generation instead), it will be too late, because it'll break compatibility with released Blazor WebAssembly projects.
Otherwise many devs will just look into alternatives (D, Go, Java (GraalVM)) even if that means lousing the benefits of the .NET eco-system.
Fair comment.
Here are some other live Wasm apps examples: https://github.com/unoplatform/uno#live-webassembly-apps.
Note that .NET for WebAssembly is still in its early stages and the .NET team is likely to continue working on AOT compilation in the coming months, and the Uno team is going to help. This will be improving the payload size and performance that is currently very much lacking in that mode. Interpreted IL mode (the UADO app) is used where the AOT engine is not yet working properly, providing a base to get the framework itself progressing, while the infrastructure rest is improving.
Many of the .NET constructs are expecting exception handling (https://github.com/WebAssembly/exception-handling), which has to be emulated as it is not yet available in WebAssembly, adding significant code to the payload. Same for other features like null reference checking or indirect invocations (some may know more on that last one). Other features like lazy WebAssembly loading (for more than 4KB at least) and Interface Types to remove any Javascript (https://github.com/WebAssembly/interface-types/blob/master/p...) will also improve the actual and perceived performance significantly.
The immediate goal of the project is to provide the ability for new and existing C# apps (and not Web sites, not yet at least) to be available for non-walled garden environments. We expect the field to progress significantly in the coming years on many fronts, making this kind of apps more useful and viable.
Finally, you'll find that the Windows Calculator port to Uno is actually stretching thin the browsers resources because of the size of the Wasm payload (browser's memory and CPU is going really high because of the internal WebAssembly management). Yet, once the tiered compiler has cached the result, the load time goes down significantly.
Yet, this simple fact that a WebAssembly app needs to download everything its needing to run puts it at disadvantage with Javascript (you download a browser with all the base libraries only once, and that's not lightweight).
For now, WebAssembly apps (in general and not just .NET ones) are more similar to mobile apps than websites, just because of this significant difference.
To put it another way, instead of starting with wrapped native apis and doing wasm last. Start with browser apis and make native ports of those, then you'll get something that works well in the browser and (95% of the time IMO) will work fine in your native version as well.
There's already a plan to give WebAssembly direct access to DOM, and to any other API JavaScript would have access to, without needing a JavaScript shim. (This requires integration between WebAssembly and the JavaScript garbage collector, which is part of why it's taking time to develop.)
Can such a thing even exist?
I think we'd better install wasm libraries (both language-specific and language-agnostic) like we install browser extensions.
Yes, cross-language code sharing is being worked on.
> I think we'd better install wasm libraries (both language-specific and language-agnostic) like we install browser extensions.
How would a site know what libraries are available? How would versioning work?
This is a caching problem, best solved at the normal browser resource cache level IMO.
But then, I don't understand why you wouldnt just make it with web tech to begin with and 'port' it to native platforms with Electron.
source: been involved in quick and dirty UIs in a business for the past decade
WASM (language independence) on electron (fixed, controlled browser version) with delphi-like UI designer could work, maybe.
The same logic applies now and it's even more compelling since the tooling and performance are better now with the full LLVM WASM toolchain and more robust C# AOT compilation available, vs the dark ages when people had JSIL, Saltarelle and Bridge to choose from.
I'll also note that every major company I'm aware of that made a C# -> Browser move for their tooling eventually regretted it and started shifting away to something better, partly due to platform churn and partly due to how much was outside of their control. Electron may change the equation there enough to be good enough, we'll see - I don't know of any companies that have taken that route yet.
I don't think this is intended for public facing, low bandwidth/mobile websites.
https://floooh.github.io/sokol-html5/
These are also "write once, run anywhere" but with more focus on keeping the binary size small (both in WASM and for the native versions).
These demos start at 23 KBytes compressed and go to 537 KBytes compressed for the biggest UI sample (over half of those 537 KB is embedded TTF font data though).
At the same time, if I'd be using Qt instead of Dear ImGui to create the UI, the resulting WASM size probably would be similar to the UNO samples,
Writing cross-platform code that also works well on WASM really needs a different mindset from the ground up IMHO.
(yours top, Qt version bottom - I tried to match the font sizes visually but did not manage to decipher your code to find out exactly what they should be x) )
Sometimes you just want for code to be able to run at all, even with a sizable download, if it means you don't need to do any porting work. For example if you have many years of work on a codebase, and you can run it on the web with almost no effort, that can be really useful.
I agree that we want most things on the web to be optimized for the web. But sometimes business or other reasons matter more than code size.
Part of including unicode package itself (transitively or otherwise) has a ton of package-level vars that bloat the WASM. Also, they slow down init because a bunch of code has to be run to initialize them. Also, due to the fact that WASM doesn't have arbitrary jumping, in order to support coroutine yielding and resumption, Go's WASM support puts big br_tables[0] at the top.
A while back, I brought up some efficiency concerns w/ data size and init instruction count[1] but they were dismissed as WASM concerns not Go ones and there weren't any easy/obvious wins. Also a while back, I used an interpreter to run the Go WASM up until actual main, then bake in the data that was initialized and remove init for packages where I didn't need their values[2]. I kinda gave up on using Go and WASM after all of that, but there is real room for improvement there.
0 - https://webassembly.github.io/spec/core/exec/instructions.ht...
I see WASM more as an "accelerator". The big chunk of code continues to be Javascript that can consume WASM modules.
I dont think this case of whole complex applications in WASM will fly. It looks like ActiveX 2.0 all over again.
Of course some things will happen as full apps in WASM, but they are mostly tools people already use outside of the Web, so that particular crowd just want to reach the tool, it doesnt matter the medium.
So it's no better than Electron? I'm primarily interested in the cross-platform desktop part.
The way Unity solves this is by creating their own C# dialect, compiler and minimal runtime (without GC etc). Sort of a brute-force approach, but until the standard .NET ecosystem solves the bloat problem it would have been better to build on a different language ecosystem.
To put it another way: Adobe can ship Photoshop using Emscripten, and big companies can probably eventually ship their internal C# business apps using Uno or Blazor, but you're not going to ship either of those using Unity's stock approach without building out all of the platform APIs they stripped out and adding back runtime features that were removed. The decisions they made were perfect for games, but people building general-purpose platforms can't cut all those corners.
However, they do not guarantee that the APIs in the .Net framework will work on all platforms, as some of them are still Windows specific.
https://docs.unity3d.com/2019.1/Documentation/Manual/dotnetP...
They do take the IL generated by Rosyln and convert it to executable code using their own custom transpiler.
I think this is a fine tradeoff for certain contexts and usages, but I don't think the general usecase for WASM is to build general web applications in C# and ship all of the CLR for things like gmail.
If anything, the BCL or common libraries are too "static", where some pieces of code reference statically all features available.
One great example is JSON.NET: That library has basically one big method that type-checks all possible inputs, making unconditionally reachable every dependency for all features of the library. In this case, JSON.NET pulls the XML reader, DataSets, and many huge libraries that are generally not needed. In Uno, we generally don't AOT those libraries and use the interpreter for that (otherwise the payload would explode).
Such libraries need to be changed to be configurable, and dynamically enable dependencies as per the user's needs.
Conversely, many pieces of code are excluded by configuration because of reflection uses, but the .NET team is improving that scenario (https://devblogs.microsoft.com/dotnet/performance-improvemen...) with attributes to tag dependencies and hint the linker.
Interestingly plain C libraries often do this better than C++ libraries (e.g. too generous use of virtual-method-interfaces in C++ libraries, or making heavy use of C++ stdlib containers when simple C-style arrays would do as well).
The Unity engine also suffered from a similar problem: If you used a simple physics feature like a stabbing collision check somewhere in your code, the entire physics module was pulled in, even though the code needed for stabbing checks is only a few percent of that physics module.
This is why I'm a bit sceptical that improvements in the .NET "machinery" alone can solve this problem. You also need to restrict language features and select the right dependencies. This is a general problem, not just web-specific, it's just that reducing the output binary size typically isn't a high-priority problem outside the web.
Consider yourself lucky. It doesn't do anything on my machine except show the splash screen.
macOS 10.15.6 / Safari 14.0
The Safari Support for large WebAssembly binaries is not particularly great at this point. We hope that the Safari team will improve the performance aspects of WebAssembly, but it does not seem to be a priority at this point (see the Wasm feature map here: https://webassembly.org/roadmap).
For the iPad, the iOS built version of the same app works lots better (https://apps.apple.com/us/app/uno-calculator/id1464736591).
https://uado.platform.uno/
...loads 8.1 MBytes compressed (32 MBytes uncompressed) until the login button appears.
This simple calculator:
https://calculator.platform.uno/
...10.1 MBytes compressed, 53.8 MBytes uncompressed. Needs a splashscreen and 10 seconds to start (on a 50 MBit connection)
It's one thing to "simply" port some cross-platform-code to WASM and make it run in the browser, but making it a proper web application takes some actual effort. I feel that "efforts" like this just give WASM a bad reputation. Sorry to be blunt.