Performance Optimization
Building fast, responsive applications requires understanding performance. I’ll explore optimization techniques.
Reducing Re-renders
Use signals to isolate updates:
fn app() -> impl IntoElement {
let mut count = use_state(|| 0);
let mut text = use_state(|| String::new());
// Only this component re-renders when count changes if we pass the signal directly
// or use it in a specific scope.
// However, with signals, often the specific element binding updates.
rect()
.child(label().text(format!("Count: {}", count.read())))
.child(
Input::new()
.value(text.read().clone())
.on_change(move |e| text.set(e))
)
}
Memoization
Cache expensive computations with use_memo:
fn expensive_list() -> impl IntoElement {
let items = use_memo(|| {
(0..1000).map(|i| format!("Item {}", i)).collect::<Vec<_>>()
});
rect()
.children(
items.read().iter().take(100).map(|item| {
label().text(item.clone())
})
)
}
Virtualization
Use VirtualScrollView for large lists:
fn virtualized_list() -> impl IntoElement {
let items = (0..10000).map(|i| format!("Item {}", i)).collect::<Vec<_>>();
VirtualScrollView::new()
.length(items.len())
.item_size(40.0)
.builder(move |index| {
label()
.height(40.0)
.child(items[index].clone())
})
}
Efficient State Updates
Batch updates (if applicable) or simply use fine-grained signals to avoid full component re-renders.
// In Freya v0.4 with signals, writing to a signal triggers updates for observers.
// If you have related state, consider struct signals or just setting them sequentially.
// The runtime handles batched updates in the event loop.
let mut state = use_state(|| State { count: 0, text: String::new() });
// Single update
state.write().count += 1;
What’s Next
Next, I’ll cover testing your Freya applications.
Summary
- Signals provide fine-grained reactivity
use_memocaches derived stateVirtualScrollViewhandles massive datasets efficiently