Open sajagi opened 4 years ago
I found the following issue that references the same 13MB size (based on the mono runtime + your code).
https://github.com/dotnet/aspnetcore/issues/16525
This issue led me down a long rabbit-hole of additional issues, some of which are still open:
https://github.com/dotnet/aspnetcore/issues/5482 https://github.com/dotnet/aspnetcore/issues/5469
I think that until those (and more) are resolved, the size may not go down much further.
So, digging a little more, I have seen posts on the Blazor site that talk about 3-4 MB deploys. I'm not sure exactly how they are getting these smaller sizes (maybe differences in configuration), but it seems like a package <13MB should be doable.
If I can find those posts again, will reference them here.
EDIT: A thread on the mono repo to track AoT compilation and improvement of file sizes: https://github.com/mono/mono/issues/10222
Hello,
if I run the server with the flag defaultIsServer = true at src/HelloWorld.Server/HostModel.fs using a bare: dotnet run -p src/HelloWorld.Server --urls=http://0.0.0.0:8080
I get a webpage for only 396kb or 247kb over the wire (delivered gzipped by the server).
You can observe that in your browser developer console, make sure you deactivate cache and local caches. The client appears to be fast enough because of the prerender at the main page and I guess the size is smaller because the server might prerender/stream only the necessary code to run that part.
The tradeoff is that static webpages are not that practical right now and some backend server and configuration might be needed, perhaps even nginx to split the traffic between static assets and the server.
But I discovered bolero yesterday evening, if I am wrong or there are any other ways to publish a client as stripped as the streamed web version let me know!
P.S. Perhaps that whole AoT might be more useful to prepackage a desktop PWA?
What happens in server mode is that your Bolero code actually runs on the server instead of WebAssembly. It uses SignalR (ie WebSockets) to send events and return the changes to apply. So the 396kB actually don't contain any WebAssembly or F# code.
Now, regarding the size of the package, one major problem that we have in Bolero vs plain Blazor is that FSharp.Core is pretty big. And unfortunately it seems that Blazor configures the Mono linker in such a way that only System. and Microsoft. assemblies get dead code elimination, and I haven't managed to override that. So we end up delivering the entire FSharp.Core even if you only use part of it. Same for the Bolero library itself, although it's smaller.
Apparently I got everything wrong regarding the prerender server mode
You can also have a server-side prerender and still run the app as webassembly! In fact that's what the project template does by default. If you look at Pages/Host.cshtml
, there are two things that decide how rendering happens:
The contents of the main
tag decides what happens on the server side.
RenderMode.Server
renders marker comment tags that are used by the server-side SignalR to decide where to render dynamic content. It doesn't prerender your Bolero app.RenderMode.ServerPrerendered
renders these marker comment tags surrounding a prerender of your Bolero app.RenderMode.Static
renders only a prerender of your Bolero app. Therefore it is useful as a prerender for webassembly mode.RenderMode.Server
(the marker comment tags will just be ignored by the webassembly) or remove the whole @(await ...)
code and just leave <div id="main"></div>
.The script tag includes either blazor.server.js
or blazor.webassembly.js
. This decides what happens on the client: .server
establishes a SignalR connection to the server, and .webassembly
loads the app client-side in WebAssembly.
After explaining it now, I realize that it would probably be best to add a IsPrerendered
setting in HostModel
, and generate the correct combination based on it and IsServer
.
@vrescobar I just created a PR with a much cleaner configuration for server/client-side and prerendering, this will hopefully help clear things up.
I will check it next week, however none of my webpages can afford web client of 10MB or large backend instances running at scale for each active connection; infrastructure cost would grow too much in these cloud days. I can't wait to see the how it evolves because the project looks very promising as a solid webassembly framework (and truly crossplatform).
Switching from gzip to brotli compression brings the default blazor counter app from 3.7mb to about 2.84mb. I believe Bolero is using gzip. With dotnet 5 out, is this issue worth revisiting?
Edit: Telerik says its 2MB to 1.8MB
Bolero doesn't configure anything specific in this regard, so the behavior is the same as with any Blazor application. From what I can gather, Brotli-compressed files are only generated when doing dotnet publish
, but not dotnet build
(or building from VS). Then, the ASP.NET Core host is able to serve them.
Fantastic. That demo is 5.8 megabytes (for me - your screenshot says 5.9). This is a significant improvement over 13.
Below is a screenshot of loading the Bolero demo, followed by a screenshot of loading the Blazor demo. The dotnet.wasm
file is 884kb for Blazor, while the Bolero version is 2.8 mb. Is there a reason for this? Does tree shaking also occur to the runtime? I would imagine the two files should be the same, but I know very little.
Hi!
The size of the client application (downloaded to browser) of bolero-app sample (
dotnet new bolero-app
) when published in release configuration (dotnet publish -c Release
) is almost 13MB. Is this the expected size or is there a way to make it much smaller? When run in debug mode (dotnet run -c debug
) the size is almost the same. Thanks!edit: typo, clarification