fsbolero / Bolero

Bolero brings Blazor to F# developers with an easy to use Model-View-Update architecture, HTML combinators, hot reloaded templates, type-safe endpoints, advanced routing and remoting capabilities, and more.
https://fsbolero.io
Apache License 2.0
1.06k stars 54 forks source link

Question: bolero-app sample publish size #110

Open sajagi opened 4 years ago

sajagi commented 4 years ago

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

zakaluka commented 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.

zakaluka commented 4 years ago

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

vrescobar commented 4 years ago

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?

Tarmil commented 4 years ago

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.

vrescobar commented 4 years ago

Apparently I got everything wrong regarding the prerender server mode

Tarmil commented 4 years ago

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:

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.

Tarmil commented 4 years ago

@vrescobar I just created a PR with a much cleaner configuration for server/client-side and prerendering, this will hopefully help clear things up.

vrescobar commented 4 years ago

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).

dharmaturtle commented 3 years ago

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

Tarmil commented 3 years ago

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.

image

dharmaturtle commented 3 years ago

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.

image

image