Template10: Massive performance issues because of LayoutUpdated event handlers

Created on 27 Jun 2016  路  8Comments  路  Source: Windows-XAML/Template10

There are some handlers to LayoutUpdated event in Template10 code.

Quote from MSDN:

When you handle LayoutUpdated, do not rely on the sender value. For LayoutUpdated, sender is always null, regardless of where the handler is attached. This is to prevent handlers from assigning any meaning to sender, such as implying that it was that specific element that fired the event out of the visual tree. LayoutUpdated implies that something in the overall visual tree has changed, and each specific object anywhere in the tree has the option of handling this occurrence. If you're familiar with lower-level render API design, you can equate LayoutUpdated being fired as similar to a "redraw needed" flag being set as part of an object-driven, retained-mode rendering logic.

Because LayoutUpdated fires in many circumstances and isn't always specific to an object that actually changes, consider whether handling the SizeChanged event instead is more appropriate for your scenario.

I already pointed that hook on LayoutUpdated is a very dangerous thing from performance perspective. Microsoft itself discourage to use this event in many scenarios, it can be used only as a last resort and with extreme care as it will lead to performance degradation.

I already have asked why some parts of code (global-scale behaviors, first to mention) handle this dangerous event. No answer was provided.

As I already pointed, these event handlers should be removed, but we must understand why these handlers to LayoutUpdated event was attached at first place, what's the reason?

bug help wanted

Most helpful comment

Well, I believe we are using this event in error.

Use SizeChanged events to respond to layout changes

The FrameworkElement class exposes two similar events for responding to layout changes: LayoutUpdated and SizeChanged. You might be using one of these events to receive notification when an element is resized during layout. The semantics of the two events are different, and there are important performance considerations in choosing between them.

For good performance, SizeChanged is almost always the right choice. SizeChanged has intuitive semantics. It is raised during layout when the size of the FrameworkElement has been updated.
LayoutUpdated is also raised during layout, but it has global semantics鈥攊t is raised on every element whenever any element is updated. It is typical to only do local processing in the event handler, in which case the code is run more often than needed. Use LayoutUpdated only if you need to know when an element is repositioned without changing size (which is uncommon).

https://msdn.microsoft.com/en-us/windows/uwp/debug-test-perf/optimize-your-xaml-layout

All 8 comments

Some memory refreshment: #902

I provided quick-fix with #906 pull request (was accepted).
But that was only a partial solution which removed most blatant performance degradation but doesn't fix core issue which is a handling of LayoutUpdated event. I mentioned that core issue is with this event and doesn't removed these handlers in pull request because I don't know why these handlers are created at first place. No information available about reasons of this questionable and problematic technical decision.

I understand, but I thought this was already resolved. Did it get un-resolved?

@JerryNixon issue is resolved partially. While there is no extreme performance degradation on mobile ARM devices (someone reported that devices with x86 Atom CPU are also noticeably affected) because of hot-fix, moderate slowdowns are still remain, these slowdowns are progressing and became especially noticeable after couple of hours of app usage. Maybe it's not a critical issue for average app, but social apps are intended to be used for hours on mobile devices. For example, it's quite common to use social app on mobile device for couple of hours while sitting in public transport in a typical megalopolis city.

And these slowdowns even not being critical, anyway consume CPU time, drain battery power, cause tolerable but unpleasant feel of overall lack of responsiveness. So, to sum up, this issue just make Windows app on mobile device to behave like Android app. Anyway, Android users are well accustomed to this, but Windows 10 Mobile users are expecting more exciting user experience.

Core issue isn't fully addressed. It's just became tolerable.

@JerryNixon and please, can you tell me, why this event is handled? If anyone can tell me reasons of LayoutUpdated event handling, I can think how it can be avoided.

@Windows-XAML/community could you anyone point me why LayoutUpdated event is handled?

And I suggest to accept a code quality rule for a future Template10 code contributions - do not attach any handlers to this event. There are much more safe places to observe visual tree.

If you required to have a surely valid visual tree to analyze - you can override OnApplyTemplate method in custom control.

For attacheable behavior it's safe to handle Loaded event, because

In the Windows Runtime implementation, the Loaded event is guaranteed to occur after a control template is applied, and you can obtain references to objects that are created by applying the XAML template.

If requirement is plainly to have a guaranteed constructed visual tree to access from code - it's safe to handle Loaded event.

I ask you, @Windows-XAML/community - is it any practical reason to handle LayoutUpdated?
I want to understand motives why this dangerous (for app performance) event is handled?

Well, I believe we are using this event in error.

Use SizeChanged events to respond to layout changes

The FrameworkElement class exposes two similar events for responding to layout changes: LayoutUpdated and SizeChanged. You might be using one of these events to receive notification when an element is resized during layout. The semantics of the two events are different, and there are important performance considerations in choosing between them.

For good performance, SizeChanged is almost always the right choice. SizeChanged has intuitive semantics. It is raised during layout when the size of the FrameworkElement has been updated.
LayoutUpdated is also raised during layout, but it has global semantics鈥攊t is raised on every element whenever any element is updated. It is typical to only do local processing in the event handler, in which case the code is run more often than needed. Use LayoutUpdated only if you need to know when an element is repositioned without changing size (which is uncommon).

https://msdn.microsoft.com/en-us/windows/uwp/debug-test-perf/optimize-your-xaml-layout

@JerryNixon you have closed the wrong issue.
This issue is about performance problems with LayoutUpdated. Pull request resolving this problem is merged. #1112 is a new issue and it is not connected to LayoutUpdated event.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

resolutedreamer picture resolutedreamer  路  4Comments

govindrawat55 picture govindrawat55  路  6Comments

Dedecekhribecek picture Dedecekhribecek  路  13Comments

VladimirAkopyan picture VladimirAkopyan  路  8Comments

JerryNixon picture JerryNixon  路  5Comments