Optimize dashboard performance for responsive Tab key navigation
All checks were successful
Build and Release / build-and-release (push) Successful in 1m32s

- Replace 6 separate filter operations with single-pass metric categorization in update_metrics
- Reduce CPU overhead from 6x to 1x work per metric update cycle
- Fix Tab key sluggishness caused by competing expensive filtering operations
- Maintain exact same functionality with significantly better performance
- Improve UI responsiveness for host switching and navigation
- Bump version to 0.1.58
This commit is contained in:
Christoffer Martinsson 2025-11-06 11:18:39 +01:00
parent 5f6e47ece5
commit f874264e13
5 changed files with 32 additions and 46 deletions

6
Cargo.lock generated
View File

@ -270,7 +270,7 @@ checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d"
[[package]] [[package]]
name = "cm-dashboard" name = "cm-dashboard"
version = "0.1.56" version = "0.1.57"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"chrono", "chrono",
@ -292,7 +292,7 @@ dependencies = [
[[package]] [[package]]
name = "cm-dashboard-agent" name = "cm-dashboard-agent"
version = "0.1.56" version = "0.1.57"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -315,7 +315,7 @@ dependencies = [
[[package]] [[package]]
name = "cm-dashboard-shared" name = "cm-dashboard-shared"
version = "0.1.56" version = "0.1.57"
dependencies = [ dependencies = [
"chrono", "chrono",
"serde", "serde",

View File

@ -1,6 +1,6 @@
[package] [package]
name = "cm-dashboard-agent" name = "cm-dashboard-agent"
version = "0.1.57" version = "0.1.58"
edition = "2021" edition = "2021"
[dependencies] [dependencies]

View File

@ -1,6 +1,6 @@
[package] [package]
name = "cm-dashboard" name = "cm-dashboard"
version = "0.1.57" version = "0.1.58"
edition = "2021" edition = "2021"
[dependencies] [dependencies]

View File

@ -131,31 +131,31 @@ impl TuiApp {
// Only update widgets if we have metrics for this host // Only update widgets if we have metrics for this host
let all_metrics = metric_store.get_metrics_for_host(&hostname); let all_metrics = metric_store.get_metrics_for_host(&hostname);
if !all_metrics.is_empty() { if !all_metrics.is_empty() {
// Get metrics first while hostname is borrowed // Single pass metric categorization for better performance
let cpu_metrics: Vec<&Metric> = all_metrics let mut cpu_metrics = Vec::new();
.iter() let mut memory_metrics = Vec::new();
.filter(|m| { let mut service_metrics = Vec::new();
m.name.starts_with("cpu_") let mut backup_metrics = Vec::new();
|| m.name.contains("c_state_") let mut nixos_metrics = Vec::new();
|| m.name.starts_with("process_top_") let mut disk_metrics = Vec::new();
})
.copied() for metric in all_metrics {
.collect(); if metric.name.starts_with("cpu_")
let memory_metrics: Vec<&Metric> = all_metrics || metric.name.contains("c_state_")
.iter() || metric.name.starts_with("process_top_") {
.filter(|m| m.name.starts_with("memory_") || m.name.starts_with("disk_tmp_")) cpu_metrics.push(metric);
.copied() } else if metric.name.starts_with("memory_") || metric.name.starts_with("disk_tmp_") {
.collect(); memory_metrics.push(metric);
let service_metrics: Vec<&Metric> = all_metrics } else if metric.name.starts_with("service_") {
.iter() service_metrics.push(metric);
.filter(|m| m.name.starts_with("service_")) } else if metric.name.starts_with("backup_") {
.copied() backup_metrics.push(metric);
.collect(); } else if metric.name == "system_nixos_build" || metric.name == "system_active_users" || metric.name == "agent_version" {
let all_backup_metrics: Vec<&Metric> = all_metrics nixos_metrics.push(metric);
.iter() } else if metric.name.starts_with("disk_") {
.filter(|m| m.name.starts_with("backup_")) disk_metrics.push(metric);
.copied() }
.collect(); }
// Clear completed transitions first // Clear completed transitions first
self.clear_completed_transitions(&hostname, &service_metrics); self.clear_completed_transitions(&hostname, &service_metrics);
@ -166,21 +166,7 @@ impl TuiApp {
// Collect all system metrics (CPU, memory, NixOS, disk/storage) // Collect all system metrics (CPU, memory, NixOS, disk/storage)
let mut system_metrics = cpu_metrics; let mut system_metrics = cpu_metrics;
system_metrics.extend(memory_metrics); system_metrics.extend(memory_metrics);
// Add NixOS metrics - using exact matching for build display fix
let nixos_metrics: Vec<&Metric> = all_metrics
.iter()
.filter(|m| m.name == "system_nixos_build" || m.name == "system_active_users" || m.name == "agent_version")
.copied()
.collect();
system_metrics.extend(nixos_metrics); system_metrics.extend(nixos_metrics);
// Add disk/storage metrics
let disk_metrics: Vec<&Metric> = all_metrics
.iter()
.filter(|m| m.name.starts_with("disk_"))
.copied()
.collect();
system_metrics.extend(disk_metrics); system_metrics.extend(disk_metrics);
host_widgets.system_widget.update_from_metrics(&system_metrics); host_widgets.system_widget.update_from_metrics(&system_metrics);
@ -189,7 +175,7 @@ impl TuiApp {
.update_from_metrics(&service_metrics); .update_from_metrics(&service_metrics);
host_widgets host_widgets
.backup_widget .backup_widget
.update_from_metrics(&all_backup_metrics); .update_from_metrics(&backup_metrics);
host_widgets.last_update = Some(Instant::now()); host_widgets.last_update = Some(Instant::now());
} }

View File

@ -1,6 +1,6 @@
[package] [package]
name = "cm-dashboard-shared" name = "cm-dashboard-shared"
version = "0.1.57" version = "0.1.58"
edition = "2021" edition = "2021"
[dependencies] [dependencies]