terminal icon indicating copy to clipboard operation
terminal copied to clipboard

WT should start up fast: profile the startup path and trim anything that takes a while

Open ghost opened this issue 5 years ago • 38 comments

Steps to reproduce

  1. Click to launch Windows Terminal

Expected behavior

Windows Terminal should be ready instantaneously like windows console, or like Sublime Text. Windows Terminal can't be slower than windows console.

While Windows Terminal is fast compared with other tools like Visual Studio, or iTunes, it is still not fast enough for a Terminal application.

Actual behavior

It takes too long to startup. It is not ready instantaneously. It's not as fast as windows console.


maintainer note: hijacking OP for task list:

  • [x] Use exactly one ColorPickerFlyout for all tabs, and just redirect it to whatever tab activated it.
  • [x] Delayload the ColorPickerFlyout.
  • [ ] Add a setting to disable ALL fragments / dynamic profiles. The app catalog search is expensive.
    • ~Maybe we can just skip loading dynamic profiles on initial launch, unless we discover that the defaultProfile is a dynamic one...~ Nah, cause what about for defterm launches that end up matching a dynamic profile.

ghost avatar May 14 '20 12:05 ghost

I mean, the Terminal is doing a lot more than the console ever was. I'm not sure there's much more we can do to optimize our UI setup. Conhost was using basically the simplest Win32/GDI interface possible, and the Terminal needs to stand up a XAML stack. Even if we somehow had a server process that already had the settings pre-loaded, we'd still need to stand up the UI stack.

At least the Terminal is faster at processing output than the console ever was, and opening new tabs/panes is certainly faster than opening a new conhost is.

Maybe there's something we can do here to optimize the creation of the XAML stack.


7/21/2022 edit: putting this here so it doesn't ping everyone on this thread.

While investigating another issue:

image

  • parsing the json is the green column.
  • Looking for fragments is wholly 50% of the settings load cost
  • Az cloud Shell is another 20% (Just creating the IAzureConnectionStatics is that expensive? That's crazy. Hard to be sure, I don't have symbols working 😕)
  • In this trace:
    • TryLoadSettings is 44/284 for the AppHost ctor
    • ctoring the XAML resources is 62/284 for the AppHost ctor, of the 139 for just instantiating App
    • instantiating the CmdPal looks like another 30/284
    • Outside of the apphost ctor:
      • opening a new tab is like 53 (_CreateNewTabFromPane), creating the color picker flyout is 15 of that.
      • image

zadjii-msft avatar May 14 '20 13:05 zadjii-msft

and the Terminal needs to stand up a XAML stack

XAML stack means UWP?

ghost avatar May 14 '20 13:05 ghost

and the Terminal needs to stand up a XAML stack

XAML stack means UWP?

This uses a Xaml Island for now, but with WinUI 3.0 Xaml will not be tied to UWP, and can be used with Win32 code

mdtauk avatar May 14 '20 13:05 mdtauk

To be technically correct - the Terminal is a Win32 application that's using Xaml Islands to host UWP XAML content in it's window, and is (typically) run as a packaged application.

The lines between what constitutes a "UWP" and a "Win32" application are becoming more and more blurred every day, and the Terminal is a great example of a hybrid application that can utilize both technologies.

zadjii-msft avatar May 14 '20 13:05 zadjii-msft

@zadjii-msft Would it be possible to eliminate the XAML stack entirely from the equation? Using a combination of directx/directcomposition/win32 technologies to create the UI. I mean, terminal really doesn't "require" XAML, most of its UI is pretty straightforward, and should be pretty easy to do in c++. The most important part I believe is the TermControl that is needed for a minimum viable product. Have you investigated this scenario/ is there interest in it. I would love to help to make this happen. But I understand that would require significant resources, and currently, optimizing XAML is the best bet.

AnuthaDev avatar May 14 '20 16:05 AnuthaDev

I mean, that's a possibility, sure, but I think as the Terminal UI gets more elaborate, using DComp for the entire UI is going to be less and less feasible. Plus, if we do want 3rd party developers writing extensions to provide their own UI elements for the Terminal (see #4000), it'd probably be more developer-friendly to ask them to write XAML components rather than DComp visuals

zadjii-msft avatar May 14 '20 16:05 zadjii-msft

To be technically correct - the Terminal is a Win32 application that's using Xaml Islands to host UWP XAML content in it's window, and is (typically) run as a packaged application.

The lines between what constitutes a "UWP" and a "Win32" application are becoming more and more blurred every day, and the Terminal is a great example of a hybrid application that can utilize both technologies.

It looks and feels like a UWP app though. Maybe that's the problem.

ghost avatar May 14 '20 16:05 ghost

@zadjii-msft Would it be possible to eliminate the XAML stack entirely from the equation? Using a combination of directx/directcomposition/win32 technologies to create the UI. I mean, terminal really doesn't "require" XAML, most of its UI is pretty straightforward, and should be pretty easy to do in c++. The most important part I believe is the TermControl that is needed for a minimum viable product. Have you investigated this scenario/ is there interest in it. I would love to help to make this happen. But I understand that would require significant resources, and currently, optimizing XAML is the best bet.

Part of the idea for this project is to modernise the terminal UI and feature set, supporting multiple console types, and show the best of Windows.

Choosing not to implement the modern UI stack, is not within that scope. Windows 10X's shell has moved to XAML, and XAML is being decoupled from the OS and being open sourced, so the community can push it forward, without relying on new OS updates.

By the end of the year, all the code should be in the GitHub, and then the community can explore how to improve performance.

The app is using C++ and so is XAML. Being able to move out of the use of an Island will possibly bring with it some perf benefits by default

mdtauk avatar May 14 '20 16:05 mdtauk

To be technically correct - the Terminal is a Win32 application that's using Xaml Islands to host UWP XAML content in it's window, and is (typically) run as a packaged application. The lines between what constitutes a "UWP" and a "Win32" application are becoming more and more blurred every day, and the Terminal is a great example of a hybrid application that can utilize both technologies.

It looks and feels like a UWP app though. Maybe that's the problem.

It is the direction Windows is moving in, so its not like it looks like UWP, but Windows is moving towards that UI everywhere.

mdtauk avatar May 14 '20 16:05 mdtauk

It is the direction Windows is moving in, so its not like it looks like UWP, but Windows is moving towards that UI everywhere.

Well, I can't really do anything about that other than to give feedback as I am doing, and avoiding Windows updates and eventually moving out of the Windows platform.

ghost avatar May 14 '20 16:05 ghost

I mean, that's a possibility

So you're telling me there's a chance 🤣😅

I hope winUI 3.0 alleviates this situation.

AnuthaDev avatar May 14 '20 16:05 AnuthaDev

@AnuthaDev it’s nowhere near ready for primetime use (by developers who we can’t go bother when stuff goes wrong), but this repository does produce a WPF control that’s really just a standard Win32 HWND with the terminal surface on it. It’s pretty much the DirectWrite renderer wired up to a surface.

Our long term plan sees us producing composable controls other developers can integrate into their own experiences.

If only we had all the time in the world :smile:

DHowett-MSFT avatar May 14 '20 16:05 DHowett-MSFT

If only we had all the time in the world :smile:

@DHowett-MSFT Okay, serious question. Suppose somebody else does the entire work, what would your preference be XAML or win32 HWNDS (Provided that win32 significantly reduces memory consumpition and startup time)?

AnuthaDev avatar May 14 '20 16:05 AnuthaDev

WinUI Desktop will use HWNDs for it's window implementation, but will use XAML UI (which uses DirectX to render to the screen)

mdtauk avatar May 14 '20 16:05 mdtauk

Well, I can't really do anything about that other than to give feedback as I am doing, and avoiding Windows updates and eventually moving out of the Windows platform.

@phgmacedo Why would you avoid future Windows updates? WinUI 3.0 brings many benefits, and as a dev, you're never going to be forced to update WinUI either. Opting out of Windows updates seems to be counter-productive in general - or are you just making an orthogonal, abstruse gesture about your displeasure? It may be more effective to visit the new WinUI 3.0 site and assuage your worries.

oising avatar May 14 '20 17:05 oising

WinUI Desktop will use HWNDs for it's window implementation, but will use XAML UI (which uses DirectX to render to the screen)

Ah, there's a difference between HWNDs and HWND. in XAML there is only parent HWND window, while in classic win32 every control has a HWND

AnuthaDev avatar May 14 '20 17:05 AnuthaDev

WinUI Desktop will use HWNDs for it's window implementation, but will use XAML UI (which uses DirectX to render to the screen)

Ah, there's a difference between HWNDs and HWND. in XAML there is only parent HWND window, while in classic win32 every control has a HWND

Yea, that is a very classic windows concept. Every control is also a Window.

@oising I think he is maybe expressing a preference for the Win32 visual look, compared to the Windows 10/WinUI look. Could be the density of controls, or just an old school familiarity with WinForms / WPF.

mdtauk avatar May 14 '20 17:05 mdtauk

density

So, WinUI 2 started to offer a "Compact" sizing dictionary that changes control sizes to more closely match classic Win32. That might be worth investigating.

DHowett-MSFT avatar May 14 '20 17:05 DHowett-MSFT

After testing: on account of we don't have too much UI right now it doesn't really help us.

DHowett-MSFT avatar May 14 '20 17:05 DHowett-MSFT

Density keeps to the 32px min height for touch controls like buttons and text boxes I believe. The flyouts from the Add Tab button could be affected, but until WinUI 3, flyouts are not affected by setting a compact density.

mdtauk avatar May 14 '20 17:05 mdtauk

Now, I'm going to mark and minimize all the complaining about our choice in UI framework as off-topic and turn this into the issue for "make sure terminal launches fast". Kay? Kay.

DHowett-MSFT avatar May 15 '20 00:05 DHowett-MSFT

Would running WT in tray be an option? It would not necessarily improve "startup" but it would make it unnoticeable. Would also fix quake mode not running unless there's a WT window open.

vannomad avatar Jul 07 '21 17:07 vannomad

Sure, that's more of a request we're working on over in #9996.

zadjii-msft avatar Jul 07 '21 17:07 zadjii-msft

@vannomad It's well known that windows terminal is extremely slow.

I've been using wezterm for a while. It does not mantain a tray icon, and it is lightning fast, starts up instantly! And even then people complain that wezterm is slow It most definitely is not slow compared to windows terminal.

rushfan000 avatar Jul 08 '21 22:07 rushfan000

One thing I didn't see mentioned: Terminal currently starts up slow enough that if you hit enter and start typing, you will not only lose key-presses, you will lose focus, meaning that terminal will never get any input until you click the window.

I.e. you type terminal in the start menu, hit enter, then type "dir" or whatever, that first 'd' will happen long before terminal is actually active, so it gives focus to something else. Where does that keypress go? The "next" window? I'm not sure! Wherever it goes, it activates that window, which then prevents Terminal from getting focus once it gets around to actually launching. And at that point, Terminal will just be an inactive window that doesn't get any input until you take some manual action to give it focus.

So, at a bare minimum: Terminal needs to start up and immediately take focus, then buffer all the input keys so they can be fed to the command line. This needs to happen fast enough that I don't lose focus.

That's the bare minimum, but really in 2021 you shouldn't be able to say "one Mississippi" before a simple app like Terminal is not only launched and activated, but fully initialized. ​That's an eternity. Really, terminal should be up and running and fully initialized before the key-up event on the enter key that launched it. I realize this is a hard problem because it's very likely the problem is in the UWP/XAML stack. Indeed, calculator suffers from the exact same problem these days, where the new version of the app loses input because it is just sooooo slow to launch. So I get that this may not be something you can entirely fix on your own, but you can add a requirement to the XAML folks to improve their startup performance (as well as do whatever you can do on your own side to mitigate the problem).

Re: the suggestion above about removing XAML, I don't think it's as crazy as it may seem. Indeed, I would argue that taking a XAML dependency in Terminal (and Calculator) before verifying that its performance was acceptable was a mistake. Backing out of that mistake until XAML achieves acceptable performance for core apps like Terminal and Calculator is not at all unreasonable IMO. It really doesn't seem like you actually need XAML for the core window/terminal area at all (maybe keep it for settings and initialize it asynchronously?). It's obviously preferable if XAML can be improved, but if it doesn't improve, the priority should be to meet your users' needs (even if that means not using some newfangled UI frameworks that aren't yet up to par).

ssylvan avatar Jul 09 '21 18:07 ssylvan

One thing I didn't see mentioned: Terminal currently starts up slow enough that if you hit enter and start typing, you will not only lose key-presses, you will lose focus, meaning that terminal will never get any input until you click the window.

Yeah, I'm none-too-pleased about that. We're booking launch time perf into 1.11 thanks to this and other discussions (and regressions :|)

DHowett avatar Jul 09 '21 19:07 DHowett

Just did a quick trace with some selected events: image

So while XAML is indeed taking up a fair mount of time, it doesn't seem like it's responsible for most of it. For example, do we really need to wait until >1s in before we launch the processes for conhost and cmd.exe? Or could we launch them right away (in parallel with all the other processes that launch, and in parallel with XAML initialization)? And why is this ScriptedSandbox64 launched so late compared to the rest of the processes (no idea what that is).

Note that nothing really happens until 240ms in, so I guess that's the sort of "floor" of how long windows takes to launch anything (and maybe launching via VS is an issue here too).

Looking at the UI thread: image

Again we see a big gap before anything happens at all on the UI thread, but then there's another big gap in the center before we reach the steady state rendering at the end. That middle gap seems to be mostly about the setup that happens in the render thread initialization (part of this is a slow initial render I think?): image

Perhaps the render thread could be initialized at the very beginning of the process launch rather than waiting for XAML (and conhost/cmd.exe etc.) to finish first? So that it's (hopefully) ready to go by the time it's needed? Seems like it currently needs the swapchain to initialize, so I'd recommend trying to refactor that so you can get most things initialized (esp. DirectX, DirectWrite, etc.), and then resize at the end and wire it up to XAML.

ssylvan avatar Jul 09 '21 20:07 ssylvan

One of my takeaways from https://github.com/microsoft/terminal/issues/6409 / https://github.com/microsoft/microsoft-ui-xaml/issues/2648 was that XAML stack also loads a lot of useless libraries (even including Maps control) and probably this requires at least some useless accesses to hard disk

vadimkantorov avatar May 31 '22 13:05 vadimkantorov

I just want to add feedback for this particular issue:

  • Currently, the Windows Terminal (1.14.1962.0) cold startup with the default profile of CMD takes at least 3-4 seconds on a new powerful machine: i9-12900K @ 5GHz with plenty of 32GB RAM and NVMe PCIe Gen4 disk ...
  • Idk what is going on but I tried to eliminate every possible setting to reduce the startup cost, but it's still very noticable for me.
    • I tried fresh reinstall of the app, purging the settings folder, installing from the Store/winget/etc... nothing helps.
    • Using the Process Explorer from the SysInternals tools, I can see that WT initialization takes significant time, after which, cmd/powershell is started instantly.

Is that the case for anyone else or it's just me?

bozhodimitrov avatar Jul 26 '22 16:07 bozhodimitrov

Idk what is going on

Ultimately, that's what's important- knowing what is going on here. Measurements of how long it takes on various CPUs isn't helpful. Actual traces of the startup, which can identify the bits of startup that are taking the longest, that's what's actually important to this thread. I've got some traces higher up that we're starting with. We'll start there, unless someone can narrow down some part of XAML init that's more costly that we can trim out.

zadjii-msft avatar Jul 26 '22 16:07 zadjii-msft