Muhammad Hamza f0209c786f
Prepare for Yew 0.20 (#2973)
* 0.20 Changelog

* Improve changelog generator

* Add blog post

* Add blog post

* Apply suggestions from code review

Co-authored-by: WorldSEnder <WorldSEnder@users.noreply.github.com>
Co-authored-by: Julius Lungys <32368314+voidpumpkin@users.noreply.github.com>

* update Changelog

* update Cargo.toml

* changelog gen compiles

* website version 0.20

* add migration guides

* prettier

* i18n

Co-authored-by: WorldSEnder <WorldSEnder@users.noreply.github.com>
Co-authored-by: Julius Lungys <32368314+voidpumpkin@users.noreply.github.com>
2022-11-25 15:19:07 +05:00

119 lines
6.0 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
description: 加速你的專案
---
# 優化與最佳實例
## neq_assign
當元件從父元件接收到屬性時, `change` 的方法就會被呼叫。除了讓你更新元件的狀態,也讓你回傳,決定元件是否要在屬性改變時,重新渲染自己的布林值 `ShouldRender` 。
重新渲染是很浪費效能的,儘可能避免這麼做。一般來說,只有在屬性真的改變時,才重新渲染。下面的程式碼是體現這個原則的例子,當屬性改變時,才回傳 `true`
```rust
use yew::ShouldRender;
#[derive(PartialEq)]
struct ExampleProps;
struct Example {
props: ExampleProps,
};
impl Example {
fn change(&mut self, props: ExampleProps) -> ShouldRender {
if self.props != props {
self.props = props;
true
} else {
false
}
}
}
```
但我們可以走的更遠!這六行的模板,使用一個 trait 和一個 實作了 `PartialEq` 的 blanket implementation ,可以被縮短至一行。請參考[這裡](https://docs.rs/yewtil/*/yewtil/trait.NeqAssign.html) `yewtil` 的 crate 裡的 `NeqAssign` trait。
## RC
為了避免重新渲染時,複製大量的資料來建立屬性,我們可以使用智慧指針來讓程式只複製指針。如果你使用 `Rc<_>` 來封裝你的屬性,而不是未封裝的值,你可以使用 `Rc::make_mut`,去複製與存取你想要改變的資料的可變參考,這做到了延遲複製,直到你需要更動子元件的資料。透過避免複製直到有值改變,子元件可以在 `Component::change` 拒絕與他狀態中的屬性相同值的屬性,而且這樣不會有任何效能成本。另外,這個方式,資料必須在與子元件比較與被拒絕之前,被複製進父元件的屬性中。
這個優化最那些無法 `Copy` 的資料型別最有用。如果你可以輕易複製你的資料,那把資料放進智慧指針裡面似乎就沒有這麼值得。對於那些包含很多像是 `Vec` 、 `HashMap` 與 `String` 的結構,這個優化對他們會更值得。
如果子元件幾乎不會更新值,那這個優化效果會很好,甚至如果父元件也很少更新,那效果會更好。上面的情況,使在純元件中使用 `Rc<_>s` 是一個封裝屬性值很好的選擇。
## View 方法
出於程式碼的可讀性,通常會寫方法包裝複雜的 `html!`,這樣你可以避免巢狀的 HTML 造成過多的向右縮排。
## 純元件/函數式元件
純元件 是一種不會改變自己狀態的元件,他們只單純顯示內容或是向普通可變的元件傳送訊息。他們和 view 方法不同的地方在於們可以在 `html!` 巨集中使用,語法會像(`<SomePureComponent />`),而不是表達式語法(`{some_view_function()}`),而且根據他們的實作方式,他們可以被 memoized這樣可以套用前面所述的 `neq_assign` 的邏輯避免重新渲染。
Yew 本身不支援純元件或是函數式元件,但是你可以透過 external crates 使用。
函數式元件還不存在,但是理論上純元件可以透過巨集與宣告方法產生。
## Keyed DOM nodes when they arrive
## 使用 Cargo Workspaces 加速編譯
Yew 最大的缺點就是花太多時間在編譯上了。編譯時間似乎和 `html!` 巨集中的程式碼質量相同。 對於小專案來說,這應該不是什麼大問題,但是對於有很多頁面的大型網頁應用程式來說,就必須要將程式碼封裝成很多 crates 以減少編譯所花的時間。
你應該將路由與頁面區塊封裝成一個 main crate然後將共用的程式碼與元件封裝成另一個 crate將每個頁面會用到的不同的元件各自封裝到不同的 crate 中,或是只產生 `Html` 的大方法中。最好的狀況,你只需要重新編譯你 main crate 與修改的頁面的 crate 的程式碼;而最壞的情況,你編輯了共用的 crate你就必須重新編譯所有依賴這個共用 crate 的程式碼。
如果你的 main crate 太過龐大,或是你希望快速迭代深層巢狀的頁面(一個頁面渲染另一個頁面的頂層),你可以使用範例的 crate ,在一個簡單的主頁面上編輯你未完成的元件。
## 編譯大小的優化 <a id="build-size-optimization"></a>
- 優化 Rust 的程式碼
- `cargo.toml` (定義釋出的設定檔)
- 使用 `wasm-opt` 優化 wasm 程式碼
更多關於程式碼大小的資訊,請參考: [rustwasm book](https://rustwasm.github.io/book/reference/code-size.html#optimizing-builds-for-code-size)
### Cargo.toml <a id="cargo-toml"></a>
你可以設定你的發行版本更小的檔案大小,透過設定 `Cargo.toml` 的 `[profile.release]` 。
[Rust profiles documentation](https://doc.rust-lang.org/cargo/reference/profiles.html)
```rust
[profile.release]
# less code to include into binary
panic = 'abort'
# optimization over all codebase ( better optimization, slower build )
codegen-units = 1
# optimization for size ( more aggresive )
opt-level = 'z'
# optimization for size
# opt-level = 's'
# link time optimization using using whole-program analysis
lto = true
```
### wasm-opt <a id="wasm-opt"></a>
更多優化 `wasm` 程式碼大小的方法。
wasm-opt 資訊: [binaryen project](https://github.com/WebAssembly/binaryen)
Rust Wasm 中有一個關於減少 Wasm 二進位檔大小的章節:[Shrinking .wasm size](https://rustwasm.github.io/book/game-of-life/code-size.html)
- 使用`wasm-pack` 預設在發行版本編譯時優化 `wasm` 程式碼
- 直接在 wasm 檔案上使用 `wasm-opt` 。
```rust
wasm-opt wasm_bg.wasm -Os -o wasm_bg_opt.wasm
```
#### 編譯 yew/examples/ 中 最小的例子 <a id="build-size-of-minimal-example-in-yew-examples"></a>
注意: `wasm-pack` 包含對 Rust 與 wasm 程式碼的優化。而`wasm-bindgen` 只是一個單純的例子,沒有對 `Rust` 做任何優化。
| used tool | size |
| :-------------------------- | :---- |
| wasm-bindgen | 158KB |
| wasm-binggen + wasm-opt -Os | 116KB |
| wasm-pack | 99KB |