Skip to content

Commit bbfb4a9

Browse files
matt2eclaude
andauthored
fix(ui): resolve multi-second UI freeze on project selection (#475)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 61d0372 commit bbfb4a9

File tree

3 files changed

+8
-37
lines changed

3 files changed

+8
-37
lines changed

apps/staged/src-tauri/src/branches.rs

Lines changed: 4 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -694,39 +694,10 @@ pub fn list_branches_for_project(
694694
.list_branches_for_project(&project_id)
695695
.map_err(|e| e.to_string())?;
696696

697-
// Eagerly populate the workstation ID cache for any remote workspace
698-
// names we haven't seen yet, so the frontend has IDs on first load.
699-
{
700-
let cache = workstation_id_cache().lock().unwrap();
701-
let missing: Vec<String> = branches
702-
.iter()
703-
.filter(|b| b.branch_type == store::BranchType::Remote)
704-
.filter_map(|b| b.workspace_name.clone())
705-
.filter(|name| !cache.contains_key(name))
706-
.collect::<std::collections::HashSet<_>>()
707-
.into_iter()
708-
.collect();
709-
drop(cache);
710-
for name in missing {
711-
match blox::ws_info(&name) {
712-
Ok(info) => {
713-
log::debug!(
714-
"[list_branches] ws_info({}) returned workstation_id={:?}",
715-
name,
716-
info.workstation_id,
717-
);
718-
if let Some(ws_id) = info.workstation_id {
719-
if let Ok(mut cache) = workstation_id_cache().lock() {
720-
cache.insert(name, ws_id);
721-
}
722-
}
723-
}
724-
Err(e) => {
725-
log::debug!("[list_branches] ws_info({}) failed: {}", name, e);
726-
}
727-
}
728-
}
729-
}
697+
// NOTE: workstation IDs for remote branches are populated lazily by
698+
// poll_all_workspace_statuses (a single batched `ws_list` call) rather
699+
// than eagerly here. Eager per-workspace `ws_info` calls were serial and
700+
// each took ~1s, causing multi-second UI freezes on project load.
730701

731702
let mut result = Vec::with_capacity(branches.len());
732703
for branch in branches {

apps/staged/src/App.svelte

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,14 +217,12 @@
217217
// regardless of which view the user is on. See sessionStatusListener.ts.
218218
unlistenSessionStatus = await listenForSessionStatus();
219219
220-
const t0 = performance.now();
221220
try {
222221
await initPreferences();
223222
} catch (e) {
224223
console.error('Failed to initialize preferences, rendering with defaults:', e);
225224
preferences.loaded = true;
226225
}
227-
console.debug(`[Staged] preferences ready in ${Math.round(performance.now() - t0)}ms`);
228226
229227
// Restore the last viewed project (persistent store is now ready).
230228
try {

apps/staged/src/lib/features/branches/BranchCardActionsBar.svelte

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,10 @@
129129
// =========================================================================
130130
// Remote endpoint URL rewriting
131131
// =========================================================================
132+
let canResolveEndpoint = $derived(!isRemote || !!branch.workstationId);
133+
132134
function getEndpointCopyUrl(endpoint: string): string {
133-
if (!isRemote || !branch.workstationId) return endpoint;
135+
if (!canResolveEndpoint) return endpoint;
134136
try {
135137
const parsed = new URL(endpoint);
136138
const port = parsed.port || (parsed.protocol === 'https:' ? '443' : '80');
@@ -615,7 +617,7 @@
615617
{@const isStopping = execution && stoppingExecutions.has(execution.executionId)}
616618
{@const showStopIcon = altHeld && isRunning && !isStopping}
617619
{@const phase = execution ? runPhases.get(execution.executionId) : undefined}
618-
{@const hasEndpoint = phase?.type === 'running' && !!phase.endpoint}
620+
{@const hasEndpoint = phase?.type === 'running' && !!phase.endpoint && canResolveEndpoint}
619621
{@const copyUrl =
620622
hasEndpoint && phase?.type === 'running' && phase.endpoint
621623
? getEndpointCopyUrl(phase.endpoint)

0 commit comments

Comments
 (0)