Open TheFrieber opened 3 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 and thumbs upping the other issue to help us prioritize it. Thank you!
Note: You can give me feedback by thumbs upping or thumbs downing this comment.
I've been checking this and maybe #12369 + https://github.com/microsoft/microsoft-ui-xaml/issues/8088 are relevant here. I don't know. I have not found any other similar issues.
I would recommend to create a new WinUI project and try if a <TextBox>
(corresponds to <Entry>
in MAUI) there behaves the same or not. If it does, then it's a WinUI issue, otherwise it's a MAUI issue. This can speedup resolution of your issue. Also having a simple repro project helps tremendously to fix your issue faster (run app, click button, see issue).
I've been checking this and maybe #12369 + microsoft/microsoft-ui-xaml#8088 are relevant here. I don't know. I have not found any other similar issues.
I would recommend to create a new WinUI project and try if a
<TextBox>
(corresponds to<Entry>
in MAUI) there behaves the same or not. If it does, then it's a WinUI issue, otherwise it's a MAUI issue. This can speedup resolution of your issue. Also having a simple repro project helps tremendously to fix your issue faster (run app, click button, see issue).
Alright, so first things first. I did debug where the most process time lies on: (Debug log from the end of the generation. ~400 Tokens)
OnPropertyChanged of Text took: 141 ms
AppendText took: 144 ms
Format took: 1 ms
https://github.com/user-attachments/assets/49a3cd95-c8ef-4243-b73f-63171fbc9565
Stopwatch Implementation:
public void AppendText(string additionalText)
{
text += additionalText;
var stopwatchAppendText = new Stopwatch();
stopwatchAppendText.Start();
OnPropertyChanged(nameof(Text));
stopwatchAppendText.Stop();
Console.WriteLine($"OnPropertyChanged of Text took: {stopwatchAppendText.ElapsedMilliseconds} ms");
}
In the 3 Days i could reduce the lag time a little by optimizing my code and debugging with stopwatches. And now it's clearly an Issue with WinUI or MAUI.
To check whether it is WinUI or MAUI, i don't know which preset to select. There is nothing under WinUI (Presets). Should i use WPF?
var stopwatchAppendText = new Stopwatch();
is not great. A better idiom is:
[ThreadStatic]
private static Stopwatch? stopwatch; // Then: var sw = stopwatch ??= new(); sw.Restart();
but that's not really important right now.
One thing that feels wrong to me is that you (likely) call AppendText(string additionalText)
whenever you have a new word. You can have a producer/consumer problem[^1] even if MAUI were blazing fast.
It should be IMHO designed like this:
AppendText(string additionalText)
.AppendText(string additionalText)
does not call OnPropertyChanged
unless the previous change was applied. I would try to subscribe editor.TextChanged += OnEditorTextChanged
and have a helper flag (bool callOnTextPropertyChanged
) to decide if OnPropertyChanged(nameof(Text));
should be called again or not.This should put less strain on UI as it might have more breathing room to display words at its pace. The downside is that you might sometimes show two or more words at a time and not one as is your intention.
[^1]: Obviously you have, hence this issue.
To check whether it is WinUI or MAUI, i don't know which preset to select. There is nothing under WinUI (Presets). Should i use WPF?
I suggested to create vanilla WinUI 3 application (https://learn.microsoft.com/en-us/windows/apps/winui/winui3/create-your-first-winui3-app) and test it there to avoid MAUI being involved.
var stopwatchAppendText = new Stopwatch();
is not great. A better idiom is:[ThreadStatic] private static Stopwatch? stopwatch; // Then: var sw = stopwatch ??= new(); sw.Restart();
but that's not really important right now.
One thing that feels wrong to me is that you (likely) call
AppendText(string additionalText)
whenever you have a new word. You can have a producer/consumer problem1 even if MAUI were blazing fast.It should be IMHO designed like this:
- Whenever you have a new word, call
AppendText(string additionalText)
.AppendText(string additionalText)
does not callOnPropertyChanged
unless the previous change was applied. I would try to subscribeeditor.TextChanged += OnEditorTextChanged
and have a helper flag (bool callOnTextPropertyChanged
) to decide ifOnPropertyChanged(nameof(Text));
should be called again or not.This should put less strain on UI as it might have more breathing room to display words at its pace. The downside is that you might sometimes show two or more words at a time and not one as is your intention.
Footnotes
- Obviously you have, hence this issue. ↩
That's what i am doing literally (Look first post):
if (!isRunning) //Anti-Lag: Workaround, so the UI responses at all.
{
MainThread.InvokeOnMainThreadAsync(() =>
{
isRunning = true;
aiMessage.AppendText(newText); //PERFORMANCE ISSUE
previousTextLength = rangeText.Length;
MessagingCenter.Send(this, "ScrollToBottom", new ScrollToBottomMessage(true));
isRunning = false;
});
}
By the way, this is a label not an editor
To check whether it is WinUI or MAUI, i don't know which preset to select. There is nothing under WinUI (Presets). Should i use WPF?
It's not about a preset. I suggested to create vanilla WinUI 3 application (https://learn.microsoft.com/en-us/windows/apps/winui/winui3/create-your-first-winui3-app) and test it there to avoid MAUI being involved.
Thank you for giving me the link. Apparently, my vs2022 doesn't have those presets that are used in that link. I'll look into that and create an application and post the results back.
To check whether it is WinUI or MAUI, i don't know which preset to select. There is nothing under WinUI (Presets). Should i use WPF?
It's not about a preset. I suggested to create vanilla WinUI 3 application (https://learn.microsoft.com/en-us/windows/apps/winui/winui3/create-your-first-winui3-app) and test it there to avoid MAUI being involved.
Thank you for giving me the link. Apparently, my vs2022 doesn't have those presets that are used in that link. I'll look into that and create an application and post the results back.
Ah, right, one has to install appropriate workload to Visual Studio.
To check whether it is WinUI or MAUI, i don't know which preset to select. There is nothing under WinUI (Presets). Should i use WPF?
It's not about a preset. I suggested to create vanilla WinUI 3 application (https://learn.microsoft.com/en-us/windows/apps/winui/winui3/create-your-first-winui3-app) and test it there to avoid MAUI being involved.
Thank you for giving me the link. Apparently, my vs2022 doesn't have those presets that are used in that link. I'll look into that and create an application and post the results back.
Ah, right, one has to install appropriate workload to Visual Studio.
Confirmed by my side. .Net MAUI has some serious performance issues.
https://github.com/user-attachments/assets/9469d947-3b0d-4460-bd12-0d4df015de27
MauiAppPerformanceTestVerify.zip WinUI3PerformanceTestVerify.zip
To make a UI update, MAUI has to use WinRT to make a UI update. WinRT calls are expensive (in my experience) and it seems that each such call takes ~1-2 ms. So if that is an issue for you, then it's tough luck.
However, to understand your MAUI's app behavior better, you can profile it using https://github.com/dotnet/maui/wiki/Profiling-.NET-MAUI-Apps#windows--dotnet-trace and it gives you a nice visual representation where the time is lost.
To make a UI update, MAUI has to use WinRT to make a UI update. WinRT calls are expensive (in my experience) and it seems that each such call takes ~1-2 ms. So if that is an issue for you, then it's tough luck.
However, to understand your MAUI's app behavior better, you can profile it using https://github.com/dotnet/maui/wiki/Profiling-.NET-MAUI-Apps#windows--dotnet-trace and it gives you a nice visual representation where the time is lost.
No that's just much slower than you would except from an UI Framework. i repeat: It is acceptable when a large Text is SET. But it is not when you ADD.
This does indeed need some improvement, also let's continue to focus on the actual issue before trying to push into workarounds. What got analyzed until now?
Edit: I would like to mention, that's not the call. as the delay increases when text size is bigger. When i would continue to run it, we would start to see a bigger differece. (For example the video i posted earlier)
(After that it just crashed by the way)
@TheFrieber I think you have made good progress in establishing that this is a MAUI perf issue. That's good.
Regarding SET vs ADD, well, in both cases you need to make WinRT interop calls. I mentioned that just because they are not free.
But it gets slower and slower, then that's definitely interesting. I'm not sure what might be the issue.
btw: I created this PR https://github.com/dotnet/maui/pull/22650 (released in https://github.com/dotnet/maui/releases/tag/8.0.60) but I'm not really sure if the patch got to .NET 9 branch. If your Visual Studio shows this old code https://github.com/dotnet/maui/pull/22650/files#diff-6e0bbf3ab78552fc393db84d62ff02aa472a933af77ca0c93362bd0dd3e703a3 then it might be the issue.
btw: I created this PR #22650 (released in https://github.com/dotnet/maui/releases/tag/8.0.60) but I'm not really sure if the patch got to .NET 9 branch. If your Visual Studio shows this old code https://github.com/dotnet/maui/pull/22650/files#diff-6e0bbf3ab78552fc393db84d62ff02aa472a933af77ca0c93362bd0dd3e703a3 then it might be the issue.
Occours in 8.0.70 too (The VerifyTests were on version 8.0.61)
Description
When trying to set or Append to a long string (5500chars for example) that is bound to a span, the UI freezes, ~5sec in my example with 5500 chars.
Why is this an issue? When streaming text, you don't want the UI to freeze everytime you add a word after that, you don't want to have a laggy UI.
For example when streaming an long AI response. It will freeze. It's agaist UX rules. It is acceptable when a large Text is SET. But it is not when you ADD.
Steps to Reproduce
While Streaming the text:
To try it out yourself without the need to implement a Streaming function, just add something like this:
Link to public reproduction project repository
No response
Version with bug
9.0.0-preview.6.24327.7
Is this a regression from previous behavior?
Not sure, did not test other versions
Last version that worked well
Unknown/Other
Affected platforms
Windows
Affected platform versions
No response
Did you find any workaround?
Provided Above in the code: Not allowing the Stream until the last load was completed. However, this does not fix the lagging, this only allows the UI to not completely Freeze but stutter. Also the streaming is very ugly with this. Unwanted.
Relevant log output
No response