Public Access
Start the Windows client in under a second: precompile the publish, and take the cache off the UI thread
Measured on a self-contained win-x64 publish, warm disk, median of six launches from process start: the main window idle on its first screen went from 2.56 s to about 0.9 s, and the splash from 735 ms to about 430 ms. Two causes, and they were most of it. ◆ THE JIT. Every launch compiled Avalonia, the XAML, EF Core's model building and our own code method by method before anything reached the screen. The runtime pack ships precompiled; nothing else did. The head now sets PublishReadyToRun on a win-* publish, which alone took the main window to 1.4 s. It costs size — the publish grows from 146 MB to 175 MB, the Setup executable from 70 MB to 89 MB — and is conditioned on the RID so build, run and the tests are untouched. Cross-compiling it on Linux works: reproduced CI's win-x64 publish in the Alpine SDK container, and vpk pack accepts the result. ◆ THE MIGRATION RAN INLINE. EF Core's async methods over SQLite complete synchronously, so StartAsync's awaited migration and profile read ran inside Compose's dispatcher turn: a quarter to half a second during which the window could not be built. They now run on the thread pool, and the desktop head calls StartAsync before building the window rather than after, so the two overlap. The Android head already called it first and gets the thread-pool half for free. The window can now appear a few tens of milliseconds before the profile is read, which shows the existing "Opening the local cache…" card briefly — the state the splash was always meant to hand over to, and one that until now was never on screen at all. macOS and Linux would very likely gain the same from ReadyToRun; they are left out only because nothing here has timed them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
0e6bdb75db
commit
4965813b73
3 files changed
+46
-8
No files matched your search
@@ -89,6 +89,26 @@
|
||||
that is correct for nobody.
|
||||
-->
|
||||
<InvariantGlobalization>false</InvariantGlobalization>
|
||||
|
||||
<!--
|
||||
Precompiled, on a Windows publish, because a cold start here is mostly the JIT. The runtime pack's
|
||||
own assemblies already ship precompiled; ours and every package's — Avalonia, Skia's bindings, EF
|
||||
Core, SSH.NET — ship as IL, and before this every launch compiled the toolkit, the XAML and EF's
|
||||
model building method by method before anything reached the screen.
|
||||
|
||||
Measured on a self-contained win-x64 publish, warm disk, median of six launches: the splash from
|
||||
735 ms to 536 ms after the process starts, and the main window idle on its first screen from 2.6 s
|
||||
to 1.4 s. The cost is size, because each method is carried as IL and as code: the publish grows from
|
||||
146 MB to 175 MB and the Setup executable from 70 MB to 89 MB. That is the trade worth making for an
|
||||
application opened many times a day and installed once — and it is a fifth of what dropping the
|
||||
native symbols below saves, so the first install is still far smaller than it once was.
|
||||
|
||||
Conditioned on the RID rather than set outright, so a plain `dotnet build`, `dotnet run` and every
|
||||
test project referencing this one are untouched: ReadyToRun is a publish step and needs a RID to
|
||||
target. Windows only for now, because Windows is where it was measured; macOS and Linux publish the
|
||||
same way and would very likely gain the same, but nothing here has timed them.
|
||||
-->
|
||||
<PublishReadyToRun Condition="$(RuntimeIdentifier.StartsWith('win-'))">true</PublishReadyToRun>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
Reference in new issue
Block a user