microsoft / microsoft-ui-xaml

Windows UI Library: the latest Windows 10 native controls and Fluent styles for your applications
MIT License
6.3k stars 676 forks source link

Text rendering performance is embarrassingly bad #9565

Open HO-COOH opened 5 months ago

HO-COOH commented 5 months ago

Describe the bug

I happened to scroll through WingetUI's log page, and I got extremely broken framerates. I thought maybe the text was too long for winui to handle so I exported the file and opened with good-ol notepad, and guess what, it was ~5500 lines and the scrolling is butter-smooth. That's just embarrassing for winui3.

Maybe, just maybe because it uses RichTextBlock which might be slower than a regular TextBlock, so I give it another chance by using the simplest TextBlock, and nope, it's just pure bad.

Steps to reproduce the bug

  1. Create a WinUI3 C++ project, use this xaml
    <ScrollViewer>
        <TextBlock FontFamily="Consolas" Text="{x:Bind FileContent}"/>
    </ScrollViewer>
  2. In code behind,
        winrt::hstring FileContent()
        {
            std::wifstream fs{ LR"(C:\Users\Peter\Desktop\WingetUI Log.txt)" }; //just replace with a file with long text
            std::wstring content(std::istreambuf_iterator<wchar_t>{fs}, std::istreambuf_iterator<wchar_t>{});
            return winrt::hstring{ std::move(content) };
        }
  3. Build in release mode, just scroll to see for yourself.

Expected behavior

At least makes it okay-ish I guess? Or maybe I am just dumb, so document techniques to make it okay-ish?

Screenshots

Originally winget-ui vs. vscode:

https://github.com/microsoft/microsoft-ui-xaml/assets/42881734/3571b17a-f10f-47d5-932e-70d8dc362a8a

TextBlock vs. notepad:

https://github.com/microsoft/microsoft-ui-xaml/assets/42881734/bcc9071d-9827-47f6-b6a3-364e8e34ca06

NuGet package version

WinUI 3 - Windows App SDK 1.5.2: 1.5.240404000

Windows version

Windows 10 (1809): Build 17763

Additional context

No response

github-actions[bot] commented 5 months ago

Hi I'm an AI powered bot that finds similar issues based off the issue title.

Please view the issues below to see if they solve your problem, and if the issue describes your problem please consider closing this one. Thank you!

Open similar issues:

Closed similar issues:

Note: You can give me feedback by thumbs upping or thumbs downing this comment.

YourOrdinaryCat commented 5 months ago

TextBlock does not use virtualization, neither does RichTextBlock, so all that text will be rendered even if not in view. I don't think the text boxes have virtualization either (see #1842), so I suppose your best bet for now would be using a ListView - not ideal, but it should work well enough.

HO-COOH commented 5 months ago

TextBlock does not use virtualization, neither does RichTextBlock, so all that text will be rendered even if not in view. I don't think the text boxes have virtualization either (see #1842), so I suppose your best bet for now would be using a ListView - not ideal, but it should work well enough.

Using a ListView you have to do tons more work to handle text wrapping. Lacking of virtualization definitely needs to be addressed

YourOrdinaryCat commented 5 months ago

Using a ListView you have to do tons more work to handle text wrapping

As a workaround, if you have the text line by line, it should be possible to use a DataTemplate with a horizontally stretched TextBlock, and set its text wrapping mode to Wrap. But that wouldn't work if you have a bunch of text on a single line, and thinking about it a bit more, selection with that would likely be a pain, needing to be handled manually.

Lacking of virtualization definitely needs to be addressed

Agreed, this would be particularly good for edit boxes. But seeing the other issue's status, I doubt it's particularly high priority.