Module freya::_docs::performance
source · Expand description
§Performance
Collection of things to avoid and improve to have a better performance.
§1. Using use_effect to synchronize state
The use_effect
hook is sometimes missused as a synchronization between states
fn app() -> Element {
let mut state = use_signal(|| 1);
let mut double_state = use_signal(|| 1);
use_effect(move || {
// Update double_state whenever `state` changes
double_state.set(state() * 2)
});
rsx!(
label {
onclick: move |_| state += 1,
"{state} * 2 = {double_state}"
}
)
}
This is bad because we are storing a derived value (double_state) in an unnecessary reactive wrapper (signal). The flow would have been:
ⓘ
(initial) -> state: 0 , double_state: 0
(state gets updated) -> state: 1 , double_state: 0
(effect runs and updates double_state) -> state: 1 , double_state: 1
§Manual signal derivation
We can simply create a temporary variable in which to store the derived value from the signal.
Because we are reading double_state
, whenever state
changes this component function will reerun, so double_state
will always be up to date.
fn app() -> Element {
let mut state = use_signal(|| 1);
let double_state = state() * 2;
rsx!(
label {
onclick: move |_| state += 1,
"{state} * 2 = {double_state}"
}
)
}
Now, the flow would be:
ⓘ
(initial) -> state: 0 , double_state: 0
(state gets updated and double_state derived) -> state: 1 , double_state: 1
§Reactive signal derivation
We can also use use_memo
to memoize derived values. This is very useful for values that are expensive to compute (which isn’t the case with simple numeric operation)
fn app() -> Element {
let mut state = use_signal(|| 1);
let double_state = use_memo(move || state() * 2);
rsx!(
label {
onclick: move |_| state += 1,
"{state} * 2 = {double_state}"
}
)
}
The flow would be:
ⓘ
(initial) -> state: 0 , double_state: 0
(state gets updated and double_state memo run synchronously) -> state: 1 , double_state: 1