WP7 ListBoxItem ContentPresenter Measure Time - silverlight

Hopefully someone can help me or at least enlighten me a bit. After the release of the Mango Beta tools I have played a lot with the new WP7 Profiler and one thing does bothers me.
Every single listbox with just a bit more complicated items is taking forever to draw. For an example - a listbox that has item consisting of Border->Grid->6xTextBoxes (each showing single symbol) takes 303ms per listbox item. Of them 288ms are spent for the ListBoxItem's ContentPresenter Measure Time (excl.).
I know that Measure is kind of costly operation but still this is beyond madness. Any thoughts would be appreciated.

I can only confirm that MeasureOverride uses to be the most time-consuming operation. (And you don't need a profiler to find it out.) I can only guess why does it take so long.
First, MeasureOverride travels recursively through the visual tree of the ListBoxItem. Somewhere at the end of this call chain there's probably a call into native code that returns actual size.
Hence keeping simple item structure is of utmost importance.
Your structure seems to be overcomplicated. If you look at TextBox template, you will see that its structure is Grid > Border > ContentPresenter. I can't judge what is behind the ContentPresenter since I don't know your code, I just wonder why don't you use TextBlock (where possible) - it is so much more efficient.
As an experiment I would try to implement MyListBoxItem.MeasureOverride and return fixed size without calling base implementation. I have no idea if it works, but it could bring surprising results.
Second thing you may investigate when implementing your own list items is the frequency of the calls to MeasureOverride. (Or just look at the profiler output.) If the number of calls is too high, then the layout might take more loops than necessary. Perhaps there are some conflicting sizing requirements which need several steps to resolve.
You mention 40 items. That should not play any role. ListBox constructs around 3 screens of ListBoxItem's, remaining items are constructed (most often reused) on as-needed basis. If the Measure time increases by increasing the item number, then look for problem in the data implementation.

Make sure your data is fully loaded in an async action and only adding item to your ListBox is running on UI Thread
Make sure you use Grid instead of StackPanel in your template
The following article is also very useful:
http://blogs.msdn.com/b/slmperf/archive/2010/10/06/silverlight-for-windows-phone-7-listbox-scroll-performance.aspx

Related

For implementing virtualization in a non-ItemsControl, is it better to retrofit ItemContainerGenerator, or implement simple custom generation?

We're rolling our own special Items-based control/panel combo that isn't based on a subclass of ItemsControl (there are multiple reasons why we can't do this which I won't get into here) but our control does handle thousands and thousands of data items, so we'd like to implement Visual virtualization.
What we're wondering is if it makes more sense to try and bang the existing ItemContainerGenerator class into our design or roll our own virtualization method.
On the one hand, ItemContainerGenerator already handles virtualization and is very efficient, and tried-and-true code is almost always preferable to starting from scratch, but on the other, the ICG was designed specificially for use with, and relies on features of the ItemsControl, which again, this control is not. Plus, that is a container generator but in our case, we just need to generate and lay out a specific, known visual that represents the data item.
Now, perhaps I'm over-simplifying things, but all I see is a need to determine which items would be visible in the ViewPort, ensure visual representations of those items are created, measured and arranged, then discard any left-over already-created visuals. To keep track of it all, it seems a simple item-to-visual mapping scheme is all that is needed, perhaps with a ItemVisual attached property on the DataItem's ViewModel object. That way when an item is removed/destroyed, we just check if there's an existing visual, and if so, nuke it.
That said, can anyone think of a reason we shouldn't simply roll our own visual virtualization? Again, the ICG does this, but I'm wondering if that's taking a Semi to the store to get eggs.

WPF CustomControl design advice

I need to develope a WPF custom control to show the layout and connectivity of nodes in a wireless mesh network. The user needs to be able to drag the nodes around. The canvas should grown and Scrollbars should appear as required if elements get draged off the available space. The ability to zoom in/out might be required.
My first take on this is to use a ListBox derived CustomControl with a Canvas based ItemsPanelTemplate. To get things moving Im using Josh Smiths DragCanvas that allows UIElements children of the canvas to be dragged around. My "node" class is not currently UIElement derived (the DragCanvas is currently working with the ListBoxItems that wrap my nodes).
1. Is this a bacially sensible approach or should I be abonding the ListBox idea and going something lower level?
2. I have to overlay the inter node link lines - not currently sure how to go about this (as a UIElement class that is part of the ControlTemplate?)
3. A few people seem to be having a headache with scrolbars in Canvases - is this going to be an issue?
Any general or specific advice most appreciated.
Wow, not bad as a control!
I am doing something similar, but it is not so simple.
1) IMHO, the DragCanvas is a basic way to host+drag elements. Since you will have to host labels (nodes), arcs and labels again (arcs' weight), I think the DragCanvas would be harder than write a custom control by yourself.
Not everything comes easy with templating: sometime is much better the "old" approach winforms-like, or even a hybrid way.
2) As stated, I'd create a Canvas-derived panel, which will host several UIElements (labels, arcs, etc). All of them should be governed by a model+viewmodel. That's a bit harder at the beginning, but it will give you a lot of satisfaction and flexibility in the future.
3) I don't think the Canvas will give you any headache! A Canvas full of elements has always a size of zero. That leads "headaches" for those trying to add a scrollviewer.
Instead, the Canvas-derived class (above) should override the MeasureOverride method, so that its size will fit any of the hosted objects. However, it is a bit annoying the fact you cannot use negative coordinates (it will cause scrolling problems).
It's hard to describe in few lines all the work behind a similar "editor". The task isn't easy, and the problems are many.
Hope it helps, anyway.
Cheers

Rendering Thread still slow after Virtualization

At a high level my application is applying about 5 different DataTemplates to a set of ListBoxItems based on their type. These items are laid out on a canvas at specific x, y points. I implemented virtualization on my ListBox and it did not seem to improve the time it takes to complete the rendering thread's processes. It still takes about 8-12 seconds for the UI to be completely loaded and usable by the user. I thought virtualization would help fix this problem but after looking around it looks like it only helps process scrolling large amounts of data. Am I correct in this assumption and does anyone else have any other tips for improving the rendering thread. This is the only problem I am having and then my project is complete. Thanks StackOverflow!
Virtualisation means that only the items you have visible are created, then dynamically destroyed/new items created as you scroll. The alternative is all UI controls are created for all items at once.
It sounds like you have bigger problems with the rest of the app. Do you perform all loading operations on a background thread? Is the UI control tree very complex indeed? Are you displaying 100s or 1,000s of items?
We also had a lot of trouble with performance in WPF. Best way is of course to profile your application. We use ANTS Performance profiler for that, but any .NET profiler will do. We got a huge performance hit, because of the lookup of our XAML Resources. Thats the advice i can give you:
Try to minimize all resources in XAML. But not only that, also try to minimize the amount of XAML files you have. One thing you can try is to defere the loading of complex parts of your DataTemplate. Similiar to what happens when you load a JPEG in a browser, first you will see a pixelated image which will be finer after it finished loading the JPEG. To accomplish that, use a simpler DataTemplate at first and then if this is visible only load the complex template on demand or after a while.
But without more information of your specific problem, we can only guess. This is an old question of mine about a similiar subject, maybe this will help aswell.
Yes, ListBox virtualization is for scrolling. When you have a large number of items in a ListBox, enabling virtualization will make only the visible items (+ a few extra items for scrolling) render, and scrolling the ListBox replaces the data in the rendered items instead of rendering new items.
If you were to post some code, perhaps we could assist you with some performance tweaks

Is excessive nesting of WPF layout panels (e.g. Grid) computationally expensive?

folks
I have heard from a coworker that I - as a designer using Microsoft Expression Blend - should avoid using excessive nesting of panel elements, because they are computationally expensive.
For example, I tend to create the mainwindow with header and custom statusbar with grid, and then take the top panel and put a grid inside it, and if I have a message inside a rectangle on the already gridded top panel I create yet another grid, etc.
As a very layout-oriented disigner (who wants to use every screen most efficiently whatever the screen dimensions are) I know this is the best way to do it considering absolute control and flexibility, which prevent the window to resize in "unpredictable" ways ;oP
BUT...
...this friend of mine said that, if you have, say, five grids nested inside one another, if you pass the mouse over them, you generate five mouse events, which is costly.
Also, if you have too many calculations due to the too many containers asking for children sizes before the actual rendering, it can also be costly.
I had some previous experience with PyGtk, and I must say I used A LOT o layout panels for all my scripts, and even the resizing of windows never seemed to me to be specially costly, except when I had some complex canvas drawing needed to be recalculated.
Does anyone have any experience or know anything about it?
Thanks a lot for reading
There's no straight-forward answer to this, but obviously the more elements you have participating in layout, the longer the measure and arrange phases are going to take for the window. Depending on which features of which Panel types you use it could be more or less costly, but for sure the more you use the more overhead there will be during the layout calculations. You can learn more about how the layout system works by reading that entire MSDN article.
In the end this is something that, unless you've gone crazy, will not often be an issue. To find out if it is causing problems for your app I suggest using the WPF Performance Suite to do some performance testing.
Wouldn't worry about it that much, i for one did not have problems with it so far. Apply some common sense, what panels are needed in which case? Do you really need yet another panel to achieve your goal or not?
The MSDN article on this issue might be of interest since it explains a few things which are not straightforward: Optimizing Performance: Layout and Design

Ways to improve WPF UI rendering speed

In case a screen of a WPF application contains lots of primitive controls, its rendering becomes sluggish. What are the recommended ways to improve the responsiveness of a WPF application in such a case, apart from adding fewer controls and using more powerful videocard?
Is there a way to somehow use offscreen buffering or something like that?
Our team was faced with problems of rendering performance. In our case we have about 400 transport units and we should render chart of every unit with a lot of details (text labels, special marks, different geometries etc.).
In first our implementations we splitted each chart into primitives and composed whole unit's chart via Binding. It was very sad expirience. UI reaction was extremely slow.
So we decided to create one UI element per each unit, and render chart with DrawingContext. Although this was much better in performance aspect, we spent about one month improving rendering.
Some advices:
Cache everything. Brushes, Colors, Geometries, Formatted Texts, Glyphs. (For example we have two classes: RenderTools and TextCache. Rendering process of each unit addresses to shared instance of both classes. So if two charts have the same text, its preparation is executed just once.)
Freeze Freezable, if you are planning to use it for a long time. Especially geometries. Complex unfreezed geometries execute HitTest extremely slow.
Choose the fastest ways of rendering of each primitive. For example, there is about 6 ways of text rendering, but the fastest is DrawingContext.DrawGlyphs.
Use profiler to discover hot spots. For example, in our project we had geometries cache and rendered appropriate of them on demand. It seemed to be, that no improvements are possible. But one day we thought what if we will render geometries one time and cache ready visuals? In our case such approach happened acceptable. Our unit's chart has just several states. When data of chart is changed, we rebuild DrawingVisual for each state and put them into cache.
Of course, this way needs some investments, it's dull and boring work, but result is awesome.
By the way: when we turned on WPF caching option (you could find link in answers), our app hung up.
I've had the same perf issue with a heavily customized datagrid since one year, and My conclusion is:
there is basically nothing you can do
on your side (without affecting your
app, i.e.: having fewer controls or
using only default styles)
The link mentioned by Jens is great but useless in your case.
The "Optimizing WPF Application Performance" link provided by NVM is almost equally useless in my experience: it just appeals to common sense and I am confident you won't learn anything extraordinary either reading. Except one thing maybe: I must say this link taught me to put as much as I can in my app's resources. Because WPF does not reinstanciate anything you put in resource, it simply reuses the same resource over and over. So put as much as you can in there (styles, brushes, templates, fonts...)
all in all, there is simply no way to make things go faster in WPF just by checking an option or turning off an other. You can just pray MS rework their rendering layer in the near future to optimize it and in the meantime, try to reduce your need for effects, customized controls and so on...
Have a look at the new (.NET 4.0) caching option. (See here.)
I have met a similar problem and want to share my thoughts and founds. The original problem is caused by a virtualized list box that displays about 25 complex controls (a grid with a text block and a few buttons inside displaying some paths )
To research the issue I used the VisualStudio Application Timeline that allows to how much time it takes to render each control and PerfView to find out what actually WPF is doing to render each control.
By default it took about 12ms to render each item. It is rather long if you need to update the list dynamically.
It is difficult to use PerfView to analyse what heppens inside since WPF renders item in the parent-child hierarchy, but I got the common understanding about internall processes.
WPF does following to render each item in the list:
Parse template using XAML reader. As far as I can see the XAML parsing is the biggest issue.
Apply styles
Apply bindings
It does not take a lot of time to apply styles and bindings.
I did following to improve performance:
Each button has its own template and it takes a lot of time to render it. I replaced Buttons with Borders. It takes about 4-5ms to render each item after that.
Move all element settings to styles. About 3ms.
Create a custom item control with a single grid in the template. I create all child elements in code and apply styles using TryFindResources method. About 2ms in the result.
After all these changes, performance looks fine but still most time is spent on loding the ListControl.Item template and the custom control template.
4. The last step: replace a ListControl with Canvas and Scrollbar controls. Now all items are created at runtime and position is calculated manually using the MeasureOverride and ArrangeOverride methods. Now it takes <1ms to render each item from which 0.5ms is spent on TextBlock rendering.
I still use styles and bindings since they do not affect performance a lot when data is changed. You can imagine that this is not a WPF solution. But I fave a few similar lists in the application and it is possible not to use templates at all.

Resources