perf(welcome): cut first-boot cold-start + add loading affordance #20
Reference in New Issue
Block a user
Delete Branch "fix/welcome-cold-start"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
On first logon the SilverOS Welcome wizard showed nothing until WebView2 had cold-started and Blazor had booted — so the entire startup cost presented as a blank window, long enough that an operator believed first boot had failed before it finally rendered.
Launch path today:
autounattendFirstLogonCommands →cmd /c powershell … Start-Process …App.exe -Verb RunAsover a locked-down Explorer shell. The only loading affordance was a bare, unstyled<div>Loading...</div>that didn't appear until WebView2 was already up.Changes
1. Immediate native splash (the "never looks hung" fix) —
MainPage.xaml/MainPage.xaml.csA native MAUI
Gridoverlay (SilverOS wordmark + spinner + "Preparing your setup…") sits on top of theBlazorWebView. MAUI controls render in the first frame — no WebView2 / JIT dependency — so something branded is on screen immediately. It fades out on the first successful WV2NavigationCompleted.2. Seamless handoff —
wwwroot/index.html/wwwroot/css/app.cssReplaced
<div>Loading...</div>with a visually identical in-page splash (same Mercury void/electric-ice tokens). It lives inside#app, so Blazor wipes it automatically on first render. native splash → webview splash → wizard reads as one continuous loading screen, no flashes of blank.3. ReadyToRun precompile —
SilverOS.Welcome.App.csprojPublishReadyToRun=true(guarded to publish-only). Removes first-run JIT — this app runs exactly once on the slowest cold-disk path. Trimming / NativeAOT deliberately avoided (unsafe for MAUI Blazor Hybrid reflection).4. Fixed-version WebView2 runtime, baked offline —
MauiProgram.cs/build.ps1/runtime/webview2/README.mdAddresses the unresolved risk flagged in
welcome-app-spec.md:108— IoT Enterprise LTSC frequently ships no WebView2 at all. The app now pointsWEBVIEW2_BROWSER_EXECUTABLE_FOLDERat a fixed-version runtime baked next to the exe;build.ps1stages it (mirrors the drivers pattern — absent is allowed and falls back to Evergreen for VM/dev tests). Fixed-version is just files, no first-boot install step → faster and air-gap friendly. Operator instructions in the new README.Bonus — de-flashed launch —
autounattend.xmlDropped the
cmd /cwrapper and added-WindowStyle Hidden, removing the console-window flash (which itself read as "broken") and one process off the critical path. Elevation (-Verb RunAs) is retained (ApplyService needs it; silent via the baked UAC policy).Verification
dotnet publish -c Release -f net9.0-windows10.0.19041.0 -r win-x64 --self-contained true(the exact build.ps1 command) succeeds; R2RRTR\0header confirmed in App/Core/UI/framework assembliesNot covered here / follow-ups
Diaglog atC:\ProgramData\SilverMetal\welcome.logalready timestampsApp ctor → CreateWindow → BlazorWebViewInitialized → NavigationCompletedfor a direct breakdown.windows/welcome/runtime/webview2/(see README) and pin it ininputs.manifest.jsonbefore shipping LTSC media. Without it the image falls back to Evergreen (build only warns).🤖 Generated with Claude Code