question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Performance issues caused by the styling system

See original GitHub issue

When working on optimizing responsiveness of my project I’ve noticed worrying patterns that show when profiling.

Class selectors are viral and attach to all controls

Selectors in the main theme (fluent for example) like https://github.com/AvaloniaUI/Avalonia/blob/master/src/Avalonia.Themes.Fluent/DatePicker.xaml#L89 end up being added to all RepeatButton instances. This wouldn’t be a huge problem but there is another problem

Style setters are evaluated instantly Said RepeatButton style has Content property setter: https://github.com/AvaloniaUI/Avalonia/blob/master/src/Avalonia.Themes.Fluent/DatePicker.xaml#L95-L101

This means that every time RepeatButton gets styled this content template will be evaluated, control tree built, path geometry will be parsed and constructed. So detaching and attaching control again will cause this to be built again. When one is creating a lot of such controls dynamically it ends up being fairly noticeable when profiling.

Another kind of setters are the ones that use resources: https://github.com/AvaloniaUI/Avalonia/blob/master/src/Avalonia.Themes.Fluent/DatePicker.xaml#L94

Such setter will resolve SystemControlBackgroundChromeMediumLowBrush and subscribe to changes (which is not cheap since resource system has to traverse entire tree upwards to find it).

And styles generally have several such setters so it starts to add up and performance starts to degrade.

Important fact is that this style has built a content template and resolved several resources without matching. This style has no effect and in most of the cases it will never be applied. Yet everybody has to pay the price.

Such setup is making Avalonia applications feel sluggish and not responsive when new content is being added. In our case we are already careful and virtualize/recycle as much as possible but still certain content is dynamic and we end up freezing the application when styles are applied. Such slowdowns take usually less than 100ms but if we are rendering at 60 FPS this means we just skipped 6 frames applying styles and user definitely noticed it.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:5
  • Comments:20 (20 by maintainers)

github_iconTop GitHub Comments

1reaction
grokyscommented, Jul 29, 2022

I think we can close this now that #8263 has been merged!

1reaction
robloocommented, Jan 15, 2022

I think I kind of see the issue with keeping Selector here.

Selector can have restricted functionality. But I would definitely not change the syntax. Just require Selector to support only types.

but at this conceptual stage its a little difficult to see how they function together.

There are directly equivalents for both in WPF/UWP so this isn’t a new idea. See the table below summarizing all ideas.

UWP Avalonia
Style Style
TargetType Selector
Key Key
BasedOn BasedOn
- Replaces

If you used a style key in either of these cases, should it apply to Menu, MenuItem (or Button or ContentPresenter template item), or both? I’d assume the last Control type in the Selector, but this becomes a grey area and may cause some confusion.

There would be no issue here as far as I can see. We all agree in the base case that Selector is equivalent to TargetType. Therefore, Selector type is matched first, then the key is matched. If you specify a key with an incompatible type an exception is thrown. Again, this is no different than WPF/UWP. In other words, the same key can be used to reference this style anywhere the type is Menu or MenuItem (or a derivative thereorof). So it is usable for both and I don’t think we would ever need to make the assumption you mention.

Granted, changing to a containerized Styling system doesn’t fix this, I think that’s more in the lazily loading styles category only if the Selector matches,

It wouldn’t do anything for load times, yes, but evaluation of selectors would be much quicker. Children are only evaluated if the parent matches. Setters are ignored entirely for all the secondary state styles (pressed, etc.) except for the precise controls that need them. As I understand it that is the majority of the performance issue.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Best practices for improving CSS performance
Learn the best practices for improving CSS user experience, such as compressing your CSS and avoiding excessive animations.
Read more >
Improve layout performance
The Android SDK includes tools to help identify problems in your layout performance.
Read more >
How To Fix Cumulative Layout Shift (CLS) Issues
Cumulative Layout Shift is caused by content changing dimensions, or new content being injected into the page by late running JavaScript. In ...
Read more >
MUI v5: is there a performance difference between styling ...
1 Answer 1 ... This means both approach use sx prop under the hood (the slowest styling approach). The one using system properties...
Read more >
Slow or poor performance in AutoCAD Products
Issue: The response time of AutoCAD is sluggish, showing one or more of the following symptoms: Commands run slowly or hang after executed....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found