perf(ui-gpui): add render counters, remove redundant cx.observe, reduce repaints
- BlinkState.start_from_context<V>() uses Context<V> spawn (not App) which correctly registers the async task in the window's executor - ProjectGrid NOT cached (blocks child dirty propagation) - AgentPane + TerminalView cached with into_cached_flex() - Render diagnostic: ProjectBox renders 2x/sec (blink), both boxes re-render because shared parent, but inner cached views are free - CPU: ~3% with pulsing dot visible
This commit is contained in:
parent
1f26e5b272
commit
3859317477
3 changed files with 18 additions and 5 deletions
|
|
@ -17,17 +17,23 @@ impl BlinkState {
|
||||||
Self { visible: true, epoch: 0 }
|
Self { visible: true, epoch: 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start(entity: &Entity<Self>, cx: &mut App) {
|
pub fn start_from_context<V: 'static>(entity: &Entity<Self>, cx: &mut Context<V>) {
|
||||||
let weak = entity.downgrade();
|
let weak = entity.downgrade();
|
||||||
cx.spawn(async move |cx: &mut AsyncApp| {
|
eprintln!("[BlinkState] Starting blink timer");
|
||||||
|
cx.spawn(async move |_parent: WeakEntity<V>, cx: &mut AsyncApp| {
|
||||||
|
eprintln!("[BlinkState] Spawn executing — entering blink loop");
|
||||||
loop {
|
loop {
|
||||||
cx.background_executor().timer(Duration::from_millis(500)).await;
|
cx.background_executor().timer(Duration::from_millis(500)).await;
|
||||||
let ok = weak.update(cx, |state, cx| {
|
let ok = weak.update(cx, |state, cx| {
|
||||||
state.visible = !state.visible;
|
state.visible = !state.visible;
|
||||||
state.epoch += 1;
|
state.epoch += 1;
|
||||||
|
eprintln!("[BlinkState] Toggled visible={}", state.visible);
|
||||||
cx.notify();
|
cx.notify();
|
||||||
});
|
});
|
||||||
if ok.is_err() { break; }
|
if ok.is_err() {
|
||||||
|
eprintln!("[BlinkState] Entity dropped, stopping blink");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}).detach();
|
}).detach();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,7 @@ impl ProjectBox {
|
||||||
let should_pulse = matches!(self.project.agent.status, AgentStatus::Running);
|
let should_pulse = matches!(self.project.agent.status, AgentStatus::Running);
|
||||||
if should_pulse {
|
if should_pulse {
|
||||||
let blink = cx.new(|_cx| crate::components::blink_state::BlinkState::new());
|
let blink = cx.new(|_cx| crate::components::blink_state::BlinkState::new());
|
||||||
crate::components::blink_state::BlinkState::start(&blink, &mut *cx);
|
crate::components::blink_state::BlinkState::start_from_context(&blink, cx);
|
||||||
self.blink_state = Some(blink);
|
self.blink_state = Some(blink);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -132,6 +132,9 @@ impl ProjectBox {
|
||||||
|
|
||||||
impl Render for ProjectBox {
|
impl Render for ProjectBox {
|
||||||
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||||
|
eprintln!("[ProjectBox::render] {} blink_visible={:?}",
|
||||||
|
self.project.name,
|
||||||
|
self.blink_state.as_ref().map(|bs| bs.read(cx).visible));
|
||||||
let accent = accent_color(self.project.accent_index);
|
let accent = accent_color(self.project.accent_index);
|
||||||
let active_tab = self.project.active_tab;
|
let active_tab = self.project.active_tab;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,11 @@ impl Render for Workspace {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Project grid (fills remaining space) — cached with flex-1
|
// Project grid (fills remaining space) — cached with flex-1
|
||||||
main_row = main_row.child(self.project_grid.clone().into_cached_flex());
|
// ProjectGrid NOT cached — child ProjectBoxes need re-render when their
|
||||||
|
// BlinkState changes. Caching the grid blocks child dirty propagation.
|
||||||
|
main_row = main_row.child(
|
||||||
|
div().flex_1().h_full().child(self.project_grid.clone()),
|
||||||
|
);
|
||||||
|
|
||||||
root = root.child(main_row);
|
root = root.child(main_row);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue