|
| 1 | +# Optimizing |
| 2 | + |
| 3 | +*Note: This is written primarily for the web, but the main optimizations will work on other platforms too.* |
| 4 | + |
| 5 | +You might have noticed that Dioxus binaries are pretty big. |
| 6 | +The WASM binary of a [TodoMVC app](https://github.com/tigerros/dioxus-todo-app) weighs in at 2.36mb! |
| 7 | +Don't worry; we can get it down to a much more manageable 234kb. |
| 8 | +This will get obviously lower over time. |
| 9 | +For example, the new [event system](https://github.com/DioxusLabs/dioxus/pull/1402) will reduce the binary size of a hello world app to less than 100kb (with unstable features). |
| 10 | + |
| 11 | +We will also discuss ways to optimize your app for increased speed. |
| 12 | + |
| 13 | +However, certain optimizations will sacrifice speed for decreased binary size or the other way around. |
| 14 | +That's what you need to figure out yourself. Does your app perform performance-intensive tasks, such as graphical processing or tons of DOM manipulations? |
| 15 | +You could go for increased speed. In most cases, though, decreased binary size is the better choice, especially because Dioxus WASM binaries are quite large. |
| 16 | + |
| 17 | +To test binary sizes, we will use [this](https://github.com/tigerros/dioxus-todo-app) repository as a sample app. |
| 18 | +The `no-optimizations` package will serve as the base, which weighs 2.36mb as of right now. |
| 19 | + |
| 20 | +Additional resources: |
| 21 | +- [WASM book - Shrinking `.wasm` code size](https://rustwasm.github.io/docs/book/reference/code-size.html) |
| 22 | +- [min-sized-rust](https://github.com/johnthagen/min-sized-rust) |
| 23 | + |
| 24 | +## Building in release mode |
| 25 | + |
| 26 | +This is the best way to optimize. In fact, the 2.36mb figure at the start of the guide is with release mode. |
| 27 | +In debug mode, it's actually a whopping 32mb! It also increases the speed of your app. |
| 28 | + |
| 29 | +Thankfully, no matter what tool you're using to build your app, it will probably have a `--release` flag to do this. |
| 30 | + |
| 31 | +Using the [Dioxus CLI](https://dioxuslabs.com/learn/0.4/CLI) or [Trunk](https://trunkrs.dev/): |
| 32 | +- Dioxus CLI: `dx build --release` |
| 33 | +- Trunk: `trunk build --release` |
| 34 | + |
| 35 | +## Build configuration |
| 36 | + |
| 37 | +*Note: Settings defined in `.cargo/config.toml` will override settings in `Cargo.toml`.* |
| 38 | + |
| 39 | +Other than the `--release` flag, this is the easiest way to optimize your projects, and also the most effective way, |
| 40 | +at least in terms of reducing binary size. |
| 41 | + |
| 42 | +### Stable |
| 43 | + |
| 44 | +This configuration is 100% stable and decreases the binary size from 2.36mb to 310kb. |
| 45 | +Add this to your `.cargo/config.toml`: |
| 46 | + |
| 47 | +```toml |
| 48 | +[profile.release] |
| 49 | +opt-level = "z" |
| 50 | +debug = false |
| 51 | +lto = true |
| 52 | +codegen-units = 1 |
| 53 | +panic = "abort" |
| 54 | +strip = true |
| 55 | +incremental = false |
| 56 | +``` |
| 57 | + |
| 58 | +Links to the documentation of each value: |
| 59 | +- [`opt-level`](https://doc.rust-lang.org/rustc/codegen-options/index.html#opt-level) |
| 60 | +- [`debug`](https://doc.rust-lang.org/rustc/codegen-options/index.html#debuginfo) |
| 61 | +- [`lto`](https://doc.rust-lang.org/rustc/codegen-options/index.html#lto) |
| 62 | +- [`codegen-units`](https://doc.rust-lang.org/rustc/codegen-options/index.html#codegen-units) |
| 63 | +- [`panic`](https://doc.rust-lang.org/rustc/codegen-options/index.html#panic) |
| 64 | +- [`strip`](https://doc.rust-lang.org/rustc/codegen-options/index.html#strip) |
| 65 | +- [`incremental`](https://doc.rust-lang.org/rustc/codegen-options/index.html#incremental) |
| 66 | + |
| 67 | +### Unstable |
| 68 | + |
| 69 | +This configuration contains some unstable features, but it should work just fine. |
| 70 | +It decreases the binary size from 310kb to 234kb. |
| 71 | +Add this to your `.cargo/config.toml`: |
| 72 | + |
| 73 | +```toml |
| 74 | +[unstable] |
| 75 | +build-std = ["std", "panic_abort", "core", "alloc"] |
| 76 | +build-std-features = ["panic_immediate_abort"] |
| 77 | + |
| 78 | +[build] |
| 79 | +rustflags = [ |
| 80 | + "-Clto", |
| 81 | + "-Zvirtual-function-elimination", |
| 82 | + "-Zlocation-detail=none" |
| 83 | +] |
| 84 | + |
| 85 | +# Same as in the Stable section |
| 86 | +[profile.release] |
| 87 | +opt-level = "z" |
| 88 | +debug = false |
| 89 | +lto = true |
| 90 | +codegen-units = 1 |
| 91 | +panic = "abort" |
| 92 | +strip = true |
| 93 | +incremental = false |
| 94 | +``` |
| 95 | + |
| 96 | +*Note: The omitted space in each flag (e.g., `-C<no space here>lto`) is intentional. It is not a typo.* |
| 97 | + |
| 98 | +The values in `[profile.release]` are documented in the [Stable](#stable) section. Links to the documentation of each value: |
| 99 | +- [`[build.rustflags]`](https://doc.rust-lang.org/cargo/reference/config.html#buildrustflags) |
| 100 | +- [`-C lto`](https://doc.rust-lang.org/rustc/codegen-options/index.html#lto) |
| 101 | +- [`-Z virtual-function-elimination`](https://doc.rust-lang.org/stable/unstable-book/compiler-flags/virtual-function-elimination.html) |
| 102 | +- [`-Z location-detail`](https://doc.rust-lang.org/stable/unstable-book/compiler-flags/location-detail.html) |
| 103 | + |
| 104 | +## wasm-opt |
| 105 | + |
| 106 | +*Note: In the future, `wasm-opt` will be supported natively through the [Dioxus CLI](https://crates.io/crates/dioxus-cli).* |
| 107 | + |
| 108 | +`wasm-opt` is a tool from the [binaryen](https://github.com/WebAssembly/binaryen) library that optimizes your WASM files. |
| 109 | +To use it, install a [binaryen release](https://github.com/WebAssembly/binaryen/releases) and run this command from the package directory: |
| 110 | + |
| 111 | +``` |
| 112 | +wasm-opt dist/assets/dioxus/APP_NAME_bg.wasm -o dist/assets/dioxus/APP_NAME_bg.wasm -Oz |
| 113 | +``` |
| 114 | + |
| 115 | +The `-Oz` flag specifies that `wasm-opt` should optimize for size. For speed, use `-O4`. |
| 116 | + |
| 117 | +## Improving Dioxus code |
| 118 | + |
| 119 | +Let's talk about how you can improve your Dioxus code to be more performant. |
| 120 | + |
| 121 | +It's important to minimize the number of dynamic parts in your `rsx`, like conditional rendering. |
| 122 | +When Dioxus is rendering your component, it will skip parts that are the same as the last render. |
| 123 | +That means that if you keep dynamic rendering to a minimum, your app will speed up, and quite a bit if it's not just hello world. |
| 124 | +To see an example of this, check out [Dynamic Rendering](../reference/dynamic_rendering.md). |
| 125 | + |
| 126 | +Also check out [Anti-patterns](antipatterns.md) for patterns that you should avoid. |
| 127 | +Obviously, not all of them are just about performance, but some of them are. |
| 128 | + |
| 129 | +## Bundling and minifying the output JS and HTML |
| 130 | + |
| 131 | +This will be added in [dioxus/#1369](https://github.com/DioxusLabs/dioxus/pull/1369). |
0 commit comments