DioxusLabs / dioxus

Fullstack GUI library for web, desktop, mobile, and more.
https://dioxuslabs.com
Apache License 2.0
18.5k stars 703 forks source link

`dx build --release` doesn't read the `[profile.release]` table from `Cargo.toml` (`strip` doesn't work) #2352

Closed Andrew15-5 closed 1 week ago

Andrew15-5 commented 1 week ago

Problem

strip setting for release profile doesn't change the binary's file size, even though I checked the docs (and this) and it should change the binary even if by a few bytes. But it doesn't work. Or maybe normally doesn't work (I think once it did change something, but maybe not). It only works via RUSTFLAGS='-C strip=symbols'.

Steps To Reproduce

Steps to reproduce the behavior:

  1. create a project with dx new (Desktop+Tailwind)

  2. cd project_name

  3. add this to the Cargo.toml:

    [profile.release]
    # strip = "none"
    # strip = "debuginfo"
    strip = "symbols"
  4. run dx build -r

  5. see the binary size (du -b ./dist/binary_name)

  6. change the strip's value as the binary's size shouldn't change

  7. prepending RUSTFLAGS='-C strip=symbols' will apply the correct strip level

Expected behavior

strip setting for release profile should change binary's file size.

Environment:

Questionnaire

ealmloff commented 1 week ago

Dioxus doesn't read or modify your Cargo.toml. It uses cargo to build your project with the settings in your Cargo.toml.

Do you see a change in binary size when building with cargo directly?

Andrew15-5 commented 1 week ago

I didn't try the cargo-direct method, only with/without env var and config changes.

Andrew15-5 commented 1 week ago

Hmm, the data is kinda confusing:

dx build -r
7272640 ./dist/desktw symbols
7268544 ./dist/desktw debuginfo
12352256 ./dist/desktw none
7268544 ./dist/desktw (unset)

RUSTFLAGS='-C strip=?' dx build -r
7110600 ./dist/desktw   symbols
8787672 ./dist/desktw   debuginfo
11992856 ./dist/desktw none

cargo build -r
7035072 ./target/release/desktw   symbols
7035072 ./target/release/desktw   debuginfo
12065536 ./target/release/desktw none
7035072 ./target/release/desktw   (unset)

RUSTFLAGS='-C strip=?' cargo build -r
6877128 ./target/release/desktw   symbols
8503272 ./target/release/desktw   debuginfo
11708832 ./target/release/desktw none

The one thing that stands out is the dx build -rmakes smaller binary when symbols are left inside vs. everything is stripped. And for some reason, dx makes binaries bigger than cargo.

ealmloff commented 1 week ago

We use option_env!() to import some configuration by for desktop apps if you build with the CLI so that desktop settings like the window name are copied from the dioxus.toml. I would expect the binary size to be slightly larger when you build with the CLI because of that.

The difference between strip and no strip in dioxus and cargo seems pretty similar (-162040 in dx) (-157944 in cargo) so this doesn't seem like a bug in dioxus.

If you would like to minimize the size of your release binary, there are several other settings you can add to your .cargo/config.toml described in the optimization section of the reference:

[unstable]
build-std = ["std", "panic_abort", "core", "alloc"]
build-std-features = ["panic_immediate_abort"]

[build]
rustflags = [
    "-Clto",
    "-Zvirtual-function-elimination",
    "-Zlocation-detail=none"
]

# Same as in the Stable section
[profile.release]
opt-level = "z"
debug = false
lto = true
codegen-units = 1
panic = "abort"
strip = true
incremental = false

When building with nightly and those settings, the tailwind desktop bundle goes from ~5mb to ~2mb for a macOS ARM

Closing this issue as not reproducable

Andrew15-5 commented 1 week ago

We use option_env!() to import some configuration by for desktop apps if you build with the CLI so that desktop settings like the window name are copied from the dioxus.toml. I would expect the binary size to be slightly larger when you build with the CLI because of that.

Is this code inserted in the resulting binary? Or is this code from the dx? Because including short strings shouldn't make such a noticeable difference in size.

So, if I don't set any names programmatically, then the only difference between two building methods is just a few embedded strings? Like, is it typically safe to use cargo instead of dx to build things?

ealmloff commented 1 week ago

Is this code inserted in the resulting binary? Or is this code from the dx? Because including short strings shouldn't make such a noticeable difference in size.

The JSON string is compiled into the binary. It could also trigger more code in dioxus desktop to get included into the final binary because the settings in the dioxus.toml are applied

So, if I don't set any names programmatically, then the only difference between two building methods is just a few embedded strings? Like, is it typically safe to use cargo instead of dx to build things?

Yes, you can typically use cargo instead of dx if you want to. Just keep in mind, not all of the settings in your Dioxus.toml will be applied to your build and assets with manganis will not be optimized/copied

Andrew15-5 commented 1 week ago

I was able to reduce file size from 6.6 MiB to 2.9 MiB! Though this is great, the unfortunate part is that the full startup time has not been decreased. It still says at about 1.1 s (versus 0.8 s for the default Desktop + TailwindCSS project).

Andrew15-5 commented 1 week ago

Yes, you can typically use cargo instead of dx if you want to. Just keep in mind, not all of the settings in your Dioxus.toml will be applied to your build and assets with manganis will not be optimized/copied

So you probably can add a build.rs script for this instead, right? Then mimic all or most of the dx's behavior in there, and it will be about identical, but "the big selling point" is that you or someone else doesn't have to have a dx around, just the Rust toolchain.

ealmloff commented 1 week ago

So you probably can add a build.rs script for this instead, right? Then mimic all or most of the dx's behavior in there, and it will be about identical, but "the big selling point" is that you or someone else doesn't have to have a dx around, just the Rust toolchain.

Yes, we have tried to include different parts of the CLI like hot reloading and asset compression in the application or a macro before, but it ends up performing poorly because macros and build scripts run in debug mode and don't persist between recompiles

Andrew15-5 commented 1 week ago

Hmm, ok, good to know. Thanks!