From c0626b272898bdb666309222fc78a7c9c66b6045 Mon Sep 17 00:00:00 2001 From: Jepmen <46252458+brandondurandpro@users.noreply.github.com> Date: Fri, 30 Oct 2026 00:33:00 +0100 Subject: [PATCH] perf(terminal): spawn the shell off the main thread (#295) term_spawn was a synchronous Tauri command, so it ran on the main thread; starting the shell forks the IDE process, which takes tens of milliseconds with a large resident set and froze the UI each time a terminal opened. It is now async like term_is_busy, so the fork runs off the main thread. The frontend already awaited it. Co-authored-by: brandondurandpro <46252458+brandondurandpro@users.noreply.github.com> --- src-tauri/src/commands/term.rs | 4 +++- src/bindings.ts | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src-tauri/src/commands/term.rs b/src-tauri/src/commands/term.rs index 23e195264..6f2e10eae 100644 --- a/src-tauri/src/commands/term.rs +++ b/src-tauri/src/commands/term.rs @@ -4,9 +4,11 @@ use ide_terminal::{TerminalInfo, TerminalOptions}; use tauri::ipc::Channel; use tauri::{State, Window}; +/// Async to stay off the main thread: forking the IDE (its whole address space) +/// to start the shell takes tens of milliseconds, a frozen UI if run there. #[tauri::command] #[specta::specta] -pub fn term_spawn( +pub async fn term_spawn( window: Window, state: State<'_, AppState>, options: TerminalOptions, diff --git a/src/bindings.ts b/src/bindings.ts index 7bf4a4797..be8f34ba4 100644 --- a/src/bindings.ts +++ b/src/bindings.ts @@ -504,6 +504,10 @@ export const commands = { vcsChangelistsSave: (changelists: ChangelistState) => typedError(__TAURI_INVOKE("vcs_changelists_save", { changelists })), /** Create Patch › Save to file. */ vcsWritePatch: (path: string, patch: string) => typedError(__TAURI_INVOKE("vcs_write_patch", { path, patch })), + /** + * Async to stay off the main thread: forking the IDE (its whole address space) + * to start the shell takes tens of milliseconds, a frozen UI if run there. + */ termSpawn: (options: TerminalOptions, onOutput: Channel) => typedError(__TAURI_INVOKE("term_spawn", { options, onOutput })), termWrite: (id: TerminalId, data: string) => typedError(__TAURI_INVOKE("term_write", { id, data })), termResize: (id: TerminalId, cols: number, rows: number) => typedError(__TAURI_INVOKE("term_resize", { id, cols, rows })),