跳到主要內容
版本:0.21

最佳化和最佳實作

有效使用智慧指針

注意:如果你不確定本節中用到的部分術語,Rust 手冊有一個關於 智慧指針的實用章節

為避免在重新渲染時複製大量的資料來建立屬性,我們可以使用智慧指針只複製一份資料的參考,而不是資料本身。如果你在屬性和子組件中傳遞對相關資料的參考,而不是實際資料,你就可以避免複製任何資料,直到需要在子組件中修改它為止,你可以在其中使用 Rc::make_mut 來複製並取得你要更動資料的可變參考。

此作法還帶來進一步的好處,在計算道具變更是否需要讓元件重新渲染時,使用 Component::changed。這是因為,可以拿底層指標位址(也就是資料儲存在機器記憶體中的位置)來進行比較,而不必比較資料的值;假如兩個指標指向相同的資料,那麼它們指向的資料值肯定相同。請注意反面不一定成立!即使兩個指標位址不同,底層資料可能仍然相同,在這種情況下,你應該比較底層資料。

要進行此比較,你需要使用 Rc::ptr_eq,而不要只使用 PartialEq(在使用等號運算子 == 比較資料時會自動使用)。Rust 文件中有 更多關於 Rc::ptr_eq 的詳細資料

這個最佳化對於未實作 Copy 的資料類型來說最有幫助。如果你可以輕易地複製你的資料,那麼將它放在智慧指標之後就不值得了。對於可能包含大量資料的結構,像是 VecHashMapString,使用智慧指標很可能會帶來效能提升。

這個最佳化效果最理想的情況是,子資料永遠不會更新,更理想的是,它們很少會被父資料更新。這讓 Rc<_>s 成為在純元件中包裝屬性值的好選擇。

不過,必須注意,除非你本身需要在子元件中複製資料,否則這個最佳化不只無用,還會加上不必要的參考計數成本。Yew 中的道具已採用參考計數,並且內部不會複製任何資料。

檢視函數

基於程式碼易讀性的理由,移動 html! 的區塊到它們自己的函數中通常是有意義的。這樣做不只能讓程式碼更易讀,因為它可以減少縮排量,還能鼓勵採用良好的設計模式,特別是在建立可組合的應用程式時,因為這些函數可以在多個地方呼叫,有助於減少需要撰寫的程式碼量。

純元件

純組件是不會變異它們的狀態的組件,它們僅顯示內容並將訊息傳遞到正常的、可變異組件。它們與檢視函數的不同點在於它們可以使用組件語法(<SomePureComponent />)從 html! 巨集中使用,而不是表達式語法({some_view_function()})。而根據它們的實作,它們可以備忘(這表示函數一旦被呼叫,它的值就會被「儲存」起來,所以如果它被呼叫多次並擁有相同的引數時,它就不必重新計算它的值,而可以直接傳回從第一次函數呼叫中儲存下來的值),防止重新渲染相同的道具。Yew 內部會比較道具,所以只有在道具改變時 UI 才會重新渲染。

使用工作區縮短編譯時間

可以說,使用 Yew 最大的缺點就是編譯 Yew 應用程式需要很長的時間。編譯專案所花的時間似乎與傳遞到 html! 巨集的程式碼數量有關。對於較小的專案來說,這通常不是什麼問題,但對於較大的應用程式來說,將程式碼拆分到多個板條箱中是有道理的,以減少編譯器必須為應用程式所做的每個變更而做的工作量。

一種可能的方法是讓您的主板條箱處理路由/頁面選擇,然後為每個頁面製作一個不同的板條箱,其中每個頁面都可以是一個不同的組件,或只是一個產生 Html 的大函數。儲存在包含應用程式不同部分的板條箱之間的共用程式碼可以儲存在專案所依賴的單獨板條箱中。在最好的情況下,您可以從在每次編譯時重建所有程式碼改為僅重建主板條箱和您的其中一個頁面板條箱。在最壞的情況下,也就是您在「共用」板條箱中編輯某個項目時,您將回到原點:編譯依賴於該共用板條箱的所有程式碼,這可能是其他所有程式碼。

如果您的主板條箱過於繁重,或者您想快速反覆處理深度巢狀頁面(例如渲染在其他頁面頂端的頁面),您可以使用範例板條箱來建立主頁面的簡化實作,並另外渲染您正在處理的組件。

縮小二進位檔大小

  • 最佳化 Rust 程式碼
  • cargo.toml(定義發行概檔)
  • 使用 wasm-opt 最佳化 wasm 程式碼

請注意:有關縮小二進位檔大小的更多資訊,請參閱 Rust Wasm Book

Cargo.toml

您可以使用 `Cargo.toml` 中 `[profile.release]` 區段中的可用設定,將發行組態設定得更精簡。

[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 aggressive )
opt-level = 'z'
# optimization for size
# opt-level = 's'
# link time optimization using using whole-program analysis
lto = true

夜間 Cargo 組態

您也可以透過 Rust 和 Cargo 的實驗性夜間功能,獲得其他優點。若要將夜間工具鏈與 `trunk` 搭配使用,請設定 `RUSTUP_TOOLCHAIN="nightly"` 環境變數。接著,您可以在 `Cargo.toml` 中設定 Rustc 中不穩定的功能。請參閱 不穩定功能 的使用說明文件,特別是關於 build-stdbuild-std-features 的區段,以了解如何設定組態。

.cargo/config.toml
[unstable]
# Requires the rust-src component. `rustup +nightly component add rust-src`
build-std = ["std", "panic_abort"]
build-std-features = ["panic_immediate_abort"]
警告

夜間 Rust 編譯器可能會包含錯誤,例如 這一則,需要偶爾注意和調整。請小心使用這些實驗性選項。

wasm-opt

此外,也可以最佳化 `wasm` 程式碼的大小。

Rust Wasm 書籍有關於縮小 Wasm 二進位檔案大小的區段:縮小 .wasm 的大小

  • 使用在發行組建中預設最佳化 `wasm` 程式碼的 `wasm-pack`
  • 直接在 `wasm` 檔案上使用 `wasm-opt`。
wasm-opt wasm_bg.wasm -Os -o wasm_bg_opt.wasm

yew/examples/ 中「minimal」範例的建置大小

注意:`wasm-pack` 結合了 Rust 和 Wasm 程式碼的最佳化。這個範例不使用任何 Rust 大小最佳化,而是使用了 `wasm-bindgen`。

使用的工具大小
wasm-bindgen158KB
wasm-bindgen + wasm-opt -Os116KB
wasm-pack99 KB

其他讀物: