Skip to content

perf(tauri): instrument desktop startup#216

Open
pascalandr wants to merge 9 commits intoNeuralNomadsAI:devfrom
Pagecran:ready/tauri-startup-instrumentation
Open

perf(tauri): instrument desktop startup#216
pascalandr wants to merge 9 commits intoNeuralNomadsAI:devfrom
Pagecran:ready/tauri-startup-instrumentation

Conversation

@pascalandr
Copy link
Copy Markdown
Contributor

@pascalandr pascalandr commented Mar 14, 2026

Summary

  • Add startup timing markers across the Tauri host, loader screen, and UI bootstrap path.
  • Persist recent traces so startup regressions can be compared across runs instead of guessed from feel.
  • Expose first-frame and first-content milestones to make later performance work easier to validate.

Follow-ups

@pascalandr
Copy link
Copy Markdown
Contributor Author

Marking this ready for review.

This PR adds desktop startup instrumentation so later performance changes can be measured instead of judged only by feel. It records startup milestones across the Tauri host, loading screen, and UI bootstrap path.

It is also the base for follow-up perf work currently stacked on my fork:

@pascalandr pascalandr changed the base branch from main to dev March 18, 2026 19:58
@pascalandr
Copy link
Copy Markdown
Contributor Author

Updated this to target dev.

This branch was already clean against dev, so this was a base alignment rather than a larger reconstruction. The follow-up branches on my fork still stack on top of it as intended.

@pascalandr pascalandr force-pushed the ready/tauri-startup-instrumentation branch from ee62e95 to a7667c3 Compare March 18, 2026 20:29
@pascalandr
Copy link
Copy Markdown
Contributor Author

Updated this after the conflict report.

I rebuilt the branch cleanly on top of dev, force-pushed it, and verified the UI build again. The fork follow-ups that stack on top of this branch have also been restacked on the refreshed base.

@pascalandr pascalandr force-pushed the ready/tauri-startup-instrumentation branch from a7667c3 to 1ce6bfd Compare March 18, 2026 21:02
@pascalandr
Copy link
Copy Markdown
Contributor Author

Rebuilt this again on top of the latest dev after the new dev updates landed.

The refreshed branch is now pushed, the fork follow-ups were restacked again on top of it, and the PR is now mergeable.

@pascalandr pascalandr force-pushed the ready/tauri-startup-instrumentation branch from 1ce6bfd to bc57aaf Compare March 19, 2026 20:14
@pascalandr
Copy link
Copy Markdown
Contributor Author

Conflicts with dev are resolved in 38d69fc.

@shantur
Copy link
Copy Markdown
Collaborator

shantur commented Mar 23, 2026

@pascalandr - Do we really need this apart from when developing?
Can't it be worked via Performace Monitoring in Dev Tools?

@pascalandr
Copy link
Copy Markdown
Contributor Author

pascalandr commented Mar 23, 2026

@shantur - DevTools help for renderer-side startup, but not for end-to-end desktop startup. This PR measures the whole path: Tauri host/setup, window/splash, backend spawn, and renderer bootstrap. Performance Monitor attaches too late to cover the earliest startup stages reliably, especially in release builds. This is handy to quick regression check in the Tauri startup but feel free to close the PR if you don't want it in.

@shantur
Copy link
Copy Markdown
Collaborator

shantur commented Mar 25, 2026

@CodeNomadBot

I want you to perform the gatekeeper checks for latest PR state

check for regressions
check for better possible implementations
Be the PR gatekeeper

@codenomadbot
Copy link
Copy Markdown
Contributor

codenomadbot bot commented Mar 25, 2026

I reviewed the latest PR head (38d69fc) against dev as a gatekeeper pass, focusing on regression risk and implementation quality.

Verdict: not ready to merge yet. I found one likely functional gap in the startup instrumentation path, plus one smaller implementation issue.

  1. Likely missed earliest Tauri milestone
  • packages/tauri-app/src-tauri/src/main.rs:311 emits perf:startup for tauri.setup.complete during Tauri .setup().
  • The splash/listener side only starts listening later in packages/ui/src/renderer/loading/main.tsx:79.
  • Those events are not replayed, so this earliest startup marker can be lost on a normal launch. That weakens the main value of the PR: measuring the earliest desktop startup stages instead of only later renderer milestones.
  • Better implementation: buffer early host-side milestones in Rust state and expose them through a command / initial status payload, or otherwise ensure the first marker is delivered after the listener is attached.
  1. Direct UI entry path drops one recorded mark
  • packages/ui/src/main.tsx:21 records ui.main.entry, but in the non-loading path beginPerfTrace("ui.bootstrap.start", ...) at packages/ui/src/main.tsx:33 clears the trace immediately afterward.
  • That means ui.main.entry is preserved only when the loading screen path already seeded the trace, not for direct UI entry.
  • This is smaller than the first issue, but it makes the trace less internally consistent across hosts/startup paths.

Verification notes

  • I inspected the diff and did not see unrelated regressions beyond the instrumentation concerns above.
  • I attempted local verification, but this workspace is not in a fully runnable state:
    • UI typecheck / build fail because dependencies are missing in this environment (vite, solid-js, etc.).
    • Tauri cargo check also fails here because packages/tauri-app/src-tauri expects resources/server, which is absent in this checkout.
  • So I cannot give a clean runtime/build pass from this environment yet.

File-size heads-up only

  • packages/ui/src/components/message-section.tsx is already ~1297 lines.
  • packages/tauri-app/src-tauri/src/cli_manager.rs is already ~1159 lines.
  • packages/tauri-app/src-tauri/src/main.rs is already ~634 lines.

If you want, I can do a follow-up gatekeeper pass after the early-event delivery issue is addressed.

--
Yours,
CodeNomadBot

@shantur
Copy link
Copy Markdown
Collaborator

shantur commented Mar 25, 2026

@pascalandr - can you please review the issues identified by the bot

@shantur
Copy link
Copy Markdown
Collaborator

shantur commented Mar 25, 2026

@CodeNomadBot

I want you to perform the gatekeeper checks again for latest PR state

check for regressions
check for better possible implementations
Be the PR gatekeeper

@codenomadbot
Copy link
Copy Markdown
Contributor

codenomadbot bot commented Mar 25, 2026

I re-ran the gatekeeper pass on the latest PR head (0126ee9) against dev.

What I checked

  • Re-reviewed the latest diff for regression risk and implementation quality.
  • Specifically verified the two issues from the previous pass.
  • Re-ran local verification attempts; this environment still cannot complete a clean UI/Tauri build because dependencies/resources are missing from the checkout.

What improved

  • The earlier tauri.setup.complete delivery problem looks addressed: startup milestones are now buffered in Rust and replayed via cli_get_status, which is the right direction.
  • The direct UI entry trace issue also looks addressed: ui.main.entry is now preserved before ui.bootstrap.start in packages/ui/src/main.tsx:27.
  • The loading screen now also surfaces startup errors more robustly by accepting either error or message payloads.

Remaining blocker

  • packages/tauri-app/src-tauri/src/cli_manager.rs:910 still emits cli:ready before recording the cli.ready startup milestone.
  • The code then records cli.ready at packages/tauri-app/src-tauri/src/cli_manager.rs:911, but the cli:ready payload and the following cli:status emission both use the pre-recorded locked snapshot.
  • On the UI side, packages/ui/src/renderer/loading/main.tsx:101 navigates immediately when cli:ready arrives. That means the loading screen can unload before it receives the later live perf:startup event for cli.ready, and the buffered startupEvents snapshot delivered with cli:ready / cli:status does not include it either.
  • Net effect: the final cli.ready milestone can still be dropped, so the trace is still not fully reliable end-to-end.

Better implementation

  • Record cli.ready before emitting cli:ready and before emitting status, so both the live event stream and the buffered snapshot agree.
  • More generally, for milestone-style instrumentation, mutate state first and emit externally second; that avoids snapshot/event ordering drift.

Verification note

  • I still cannot give a clean build/runtime pass from this environment:
    • UI typecheck fails here because JS dependencies are not installed in this checkout.
    • Tauri cargo check still fails here because packages/tauri-app/src-tauri expects resources/server, which is absent.

Verdict

  • Better than the previous revision, but still not merge-ready because the cli.ready milestone can still be lost.

File-size heads-up only

  • packages/ui/src/components/message-section.tsx is ~1297 lines.
  • packages/tauri-app/src-tauri/src/cli_manager.rs is ~1200 lines.
  • packages/tauri-app/src-tauri/src/main.rs is ~638 lines.

If that emission order is fixed, I can run one more gatekeeper pass.

--
Yours,
CodeNomadBot

@shantur
Copy link
Copy Markdown
Collaborator

shantur commented Mar 25, 2026

@pascalandr

Can you review the blockers please

@pascalandr
Copy link
Copy Markdown
Contributor Author

@shantur
done

@shantur
Copy link
Copy Markdown
Collaborator

shantur commented Mar 25, 2026

@CodeNomadBot

I want you to perform the gatekeeper checks for latest PR state

check for regressions
check for better possible implementations
Be the PR gatekeeper

@codenomadbot
Copy link
Copy Markdown
Contributor

codenomadbot bot commented Mar 25, 2026

I re-ran the gatekeeper pass on the latest PR head (2055ed6) against dev, assuming the goal is still to validate the startup instrumentation changes for regressions and implementation quality after the follow-up fixes.

Result: my previous blocker is still present, so I still would not merge this yet.

Blocking issue

  • packages/tauri-app/src-tauri/src/cli_manager.rs:931 still emits cli:ready before recording the cli.ready startup milestone at packages/tauri-app/src-tauri/src/cli_manager.rs:932.
  • packages/tauri-app/src-tauri/src/cli_manager.rs:933 then emits cli:status using the old locked snapshot, so neither emitted snapshot includes the final cli.ready milestone.
  • On the UI side, packages/ui/src/renderer/loading/main.tsx:101 navigates immediately on cli:ready, so the loading screen can unload before the later live perf:startup event for cli.ready is observed.
  • Net result: the final readiness milestone can still be dropped, so the startup trace is still not reliable end-to-end.

What still looks good

  • Early Tauri milestones are now buffered and replayed through cli_get_status, which fixes the earlier tauri.setup.complete delivery gap.
  • The direct UI entry path now preserves ui.main.entry before ui.bootstrap.start in packages/ui/src/main.tsx:27.
  • The loading screen error handling remains improved.

Better implementation

  • Record cli.ready first, then emit cli:ready, then emit cli:status from a fresh snapshot that already contains the final startup event.
  • In general, for these milestone events, update internal state before emitting any external event payloads.

Regression notes

  • I do not see a new regression in the instrumentation logic beyond this still-open ordering bug.
  • The latest head includes a merge from dev; I did not identify a new PR-specific issue from that merge in the startup instrumentation paths.

Verification note

  • I still cannot give a clean local build/runtime pass from this environment because the checkout is missing JS dependencies and packages/tauri-app/src-tauri/resources/server.

Verdict

  • Still not merge-ready until the cli.ready ordering bug is fixed.

File-size heads-up only

  • packages/ui/src/components/message-section.tsx is ~1297 lines.
  • packages/tauri-app/src-tauri/src/cli_manager.rs is ~1221 lines.
  • packages/tauri-app/src-tauri/src/main.rs is ~638 lines.

If that ordering is corrected, I can do one more quick gatekeeper pass.

--
Yours,
CodeNomadBot

@shantur
Copy link
Copy Markdown
Collaborator

shantur commented Mar 25, 2026

@CodeNomadBot

Try again

@codenomadbot
Copy link
Copy Markdown
Contributor

codenomadbot bot commented Mar 25, 2026

I checked again.

What I understood

  • You want another gatekeeper pass on the latest PR state, focused on regressions and better implementation options.
  • I assumed the relevant question is whether the startup instrumentation branch is now safe to merge.

Current state

  • The PR head is still 2055ed6, which is the same commit I reviewed in the previous pass.
  • I re-checked the critical startup-instrumentation paths anyway.

Verdict

  • No change from the previous gatekeeper result: I still would not merge this yet.

Blocking issue still present

  • packages/tauri-app/src-tauri/src/cli_manager.rs:931 still emits cli:ready before recording cli.ready at packages/tauri-app/src-tauri/src/cli_manager.rs:932.
  • packages/tauri-app/src-tauri/src/cli_manager.rs:933 still emits cli:status from the old locked snapshot, so that snapshot also misses the final startup milestone.
  • packages/ui/src/renderer/loading/main.tsx:101 still navigates immediately on cli:ready, so the loading screen can unload before it ever observes the later live perf:startup event for cli.ready.
  • That means the final readiness milestone can still be dropped, so the trace is still not reliably complete end-to-end.

What still looks good

  • Early startup buffering and replay still look correct.
  • The direct UI entry trace preservation still looks correct.
  • I do not see a new regression beyond the still-open cli.ready ordering bug.

Best implementation fix

  • Record cli.ready first.
  • Then emit cli:ready.
  • Then emit cli:status from a fresh post-update snapshot.

Verification note

  • I still cannot provide a clean local runtime/build pass from this environment because the checkout is missing JS dependencies and packages/tauri-app/src-tauri/resources/server.

So: tried again, but the blocker is still there because the relevant code path has not changed since the previous review.

--
Yours,
CodeNomadBot

@shantur
Copy link
Copy Markdown
Collaborator

shantur commented Mar 25, 2026

@pascalandr

I can't apply changes to your branch. Please apply

diff --git a/packages/tauri-app/src-tauri/src/cli_manager.rs b/packages/tauri-app/src-tauri/src/cli_manager.rs
index afac307..3e8c50d 100644
--- a/packages/tauri-app/src-tauri/src/cli_manager.rs
+++ b/packages/tauri-app/src-tauri/src/cli_manager.rs
@@ -890,11 +890,13 @@ impl CliProcessManager {
             .ok()
             .and_then(|u| u.port_or_known_default())
             .map(|p| p as u16);
-        let mut locked = status.lock();
-        locked.port = port;
-        locked.url = Some(base_url.clone());
-        locked.state = CliState::Ready;
-        locked.error = None;
+        {
+            let mut locked = status.lock();
+            locked.port = port;
+            locked.url = Some(base_url.clone());
+            locked.state = CliState::Ready;
+            locked.error = None;
+        }
         log_line(&format!("cli ready on {base_url}"));
 
         let token = bootstrap_token.lock().take();
@@ -928,9 +930,10 @@ impl CliProcessManager {
         } else {
             navigate_main(app, &base_url);
         }
-        let _ = app.emit("cli:ready", locked.clone());
         record_startup_event(status, app, "cli.ready", json!({ "url": base_url }));
-        Self::emit_status(app, &locked);
+        let snapshot = status.lock().clone();
+        let _ = app.emit("cli:ready", snapshot.clone());
+        Self::emit_status(app, &snapshot);
     }
 
     fn emit_status(app: &AppHandle, status: &CliStatus) {

@pascalandr
Copy link
Copy Markdown
Contributor Author

Thanks

@shantur
Copy link
Copy Markdown
Collaborator

shantur commented Mar 25, 2026

@CoseNomadBot

Check new changes

@pascalandr
Copy link
Copy Markdown
Contributor Author

so this one never had his final review because of a wrong lettre calling the bot

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants