I have a page in my WP7 app that I build dynamically. I create and add 60 user controls to a grid and it takes around 5 seconds. I need to find a way of speeding this up.
The process is as follows:
Create user control
Add new grid row definition
Set the value of the control row property
Add the control to the grid.Children collection.
It is step 4 that is taking the time. I'm guessing that each time I do this the visual tree is getting re-built.
Is there any way of telling the grid to only re-build the visual tree after I have finished updating the children collection?
Or is there another better way of doing this?
UPDATE: The List Picker control from the WP7 Toolkit was causing the problem. When I changed to one I wrote myself the time taken to display the page on a phone reduced from 25 seconds to 1 second.
The/your aim is to try and reduce the number of times you update the visualtree.
A few suggestions:
Try including (some of) the items in the page by default but just change their visibility depending on what you need.
Build the whole grid in code and add it to the page in one go (rather than a line at a time)
Depending on your content, you could try using a ListBox and alternating the template used for each row to get different content displayed.
The technique which will be best for you will depend on what you're actually adding to the UI. You'll need to test to see what is best for you.
If the UI virtualization (i.e. ListBox) helped, the problem must be in your controls. Templating, bindings, converters, using Xaml instead of C# code, unnecessary Xaml constructs (such as element names), overcomplicated visual tree (e.g. unneeded grids) etc. - those are the things that can degrade the performance.
If you suspect incremental visual tree rebuilds (I don't think so), then simply debug MeasureOverride/ArrangeOverride methods.
I guess this article might give you more tips. I described there how we optimized a similarly complex control - MonthCalendar with 126 sub-controls. Control load time decreased approx. 5x!
Related
I am trying to build a form with a phone input that includes country codes. Essentially, I am trying to make something a lot like this:
I already found and cleaned a list of flags, countries, and their codes, and built the method that creates a DropdownMenuItem for an arbitrary index. I then construct a list of them and pass it to the DropdownButton widget. It's all very simple, so I don't think the code is necessary. However, because I have so many countries, and therefore menu items, the menu lags significantly when opening. So, I was wondering if drop down menus are capable of loading large numbers of widgets in a smarter fashion than it seems they do.
Can a drop down menu could load the first 10 or so widgets around the selected index and display them, as that is all that will be in view initially, and then load the rest of the widgets asynchronously? I suspect that this will require a custom drop down menu, but I am not very well versed in the implementation of Flutter's drop down menu, so I am unsure of how to proceed with this.
Any help is appreciated.
I don't think that "loading" is the actual problem here, more likely it's the rendering/building of the widgets. You can improve the situation by using something like a ListView.builder that builds items on demand.
It seems like the default dropdown system is not based on a ListView.
You can create your own version of the dropdown (like a complete customized copy of the classes), which will require quite quite a lot of work and research.
Or alternatively, use something like a SimpleDialog with an embedded ListView to display the list. Like this one for Android.
I am working with flex for the last two years on some desktop apps. Until now I never had any performance related issues but today as we completed a mobile application for the iPad, I'm facing a challenge, the application is incredibly slow on the iPad.
http://i.stack.imgur.com/qkbWn.png
Slow, means that when I press a button in the menu to change the splitview I must wait something like 5s. Then scrolling is really slow two, with less than one fps and my TextInput starts to bug (the text is not in his box anymore).
I started to read a lot of blog post and presentation about optimisation for the mobile platform and then I rewrite some of the components I use. I removed the SkinnableContainer for instance and replaced it by a VGroup including some actionScript based drawing.
Now what you see is a VGroup (the dark grey one) containing some others VGroup (the group with title here) and then each widget is an HGroup with a label and a Widget. I only use Label and TextInput for the text.
Creation time is slow even (several seconds to create the view) for another page where there is only 4 text widget on it, or another one with only a list with a custom item renderer where each row is a set of 4 labels.
The whole things is cabled with RobotLegs, with nothing fancy, one models is injected in the view and at the beginning I set a member variable on the view with this object to bind my variables.
Frankly my thinking right now is : it smells fishy because if I've done everything right it is impossible to have such low performance and thinks that flex is competitive on the mobile platform. So right now I'm trying to disable the application piece by piece to try to locate what could slow it like that. I've got a couple suspects to check, for instance I've got some binding warning to check, and then see if robotlegs has got its share of the problem.
So my main question here is what do you think, and could you have some ideas about "is there a problem" and "how do we solve it".
Thanks
Run profiler for startup and separatelly for each operation that takes longed that it needs. Then prioritize the problems and try to solve them with basic optimization techniques.
Some problems you will not be able to solve fast - e.g. time for creating big components. The only option there is to rewrite those components with AS3 without MXML, styles and anything. I'm sure that flash.text.TextField is created many times faster than mx.controls.Label. The same for other components.
When component is created, it can be reused at a very low price. In your app there must be a lot of places where you recreate while you can reuse old components. It will save you memory and time.
Layouts tend to redraw even when it's not needed. If you have a lot of nested layouts, find the most critical places and replace a series of layouts with one custom layout or even component.
This all is very developer time consuming. At the end you will not get a smooth app anyway, but I believe that it can become usable.
I know the limit for named controls is 254, beyond that you have to use control arrays. But it seems we have hit the limit for arrays too. Any idea what that absolute limit is?
There is no absolute limit. If you put enough controls on the form, you'll eventually run out of memory. I made a test app that loads command buttons into a control array. My first run stopped with an "Out of memory" error at around 6900 buttons. I shut down a few other apps and was able to load nearly 8200. I did the same thing with text boxes and got different results (about 7300 before and 8600 after). Different controls consume different amounts of memory, so there really is no way to specify an exact number of controls that you can put on a form.
We have a records management system written in VB6 and there is a UI guideline that says each record should have exactly one data entry form associated with it (i.e. can't open up other windows). As a result of this policy, one of the more complex record types in our system now has a form with a total of 659 individual controls. We had run into the 256 named controls limit, and then converted many of the controls to control arrays over time. Recently, we squeezed room for 5 or 6 new controls, after going through the entire form and converting the few remaining standalone controls to control arrays.
This is one time where I would like to break the rules, but that would involve quite a bit of refactoring to use a multiple form approach.
In any event, you can fit at least 659 controls on a form, but I've never been able to find out what the true absolute limit is (and I'm not sure that I want to).
Following on from a question I posted yesterday about GUIs, I have another problem I've been working with. This question related to calculating the bending moment on a beam under different loading conditions.
On the GUI I have developed so far, I have a number of sliders (which now work properly) and a pop-up menu which defines the load case. I would like to be able to select the load case from the pop-up menu and position the loads as appropriate, in order to define each load case in turn. The output that I need is an array defining the load case number (the rows) and a number of loading parameters (the itensity and position of the loads, which are controlled by the sliders).
The problem I am having is that I can produce this array (of the size I need) and define the loading for one load case (by selecting the pop-up menu) using the sliders, but when I change the popup menu again, the array only keeps the loading for the load case selected by the pop-up menu.
Can anyone suggest an approach I can take with (specifically to store the variables from each load case) or an example that illustrates a similar solution to the problem?
The probem may be a bit vague, so please let me know if anything needs clearing up.
Many Thanks,
James
You could use Application Data to store the current loading case and have a application data structure to store the values of each slider for the different loading cases.
In short, you could use the setappdata and getappdata to save and load the data you need. Mathworks has more information here.
I'm developing a Silverlight application that displays items in a listbox control and I've run into a bit of a performance issue.
Each item in the listbox is a custom stackpanel with some formatted text and such.
When I've got a list of 500 or less items the listbox works fine, but loading more than this causes problems. At 1000 items, Silverlight will consume 10% cpu, even if I'm not doing anything, at 3000 items the cpu constantly uses 32-36%.
This is on a dual core machine, on an older machine I tested out on the cpu usage goes way up.
This also effects the framerate, I'm getting 6fps with a 3000 item listbox, which makes the application sluggish.
Does anyone know what might be causing this? My first thought was that silverlight is trying to render all the items, even though the items are off screen... this seems to be consistant as if I insert items with their Visability.Collapsed, the extra cpu overhead is not present.
PS: I'm running in windowless="true" as I need to display some html ontop of my silverlight form.
You should use the DataGrid in Silverlight 2 because it supports UI Virtualization. It has been tested with millions of items and will only create enough visuals needed to display.
Your guess is basically correct. Although Silverlight does not attempt to render all 3000 elements in the ListBox, it still needs to create 3000 ListBoxItem objects, which in turn get Measured and Arranged during layout time, etc, only for them to get clipped at render time. Layout happens much faster when the elements are Collapsed (since there is basically nothing for layout to do in this scenario).
WPF has VirtualizingStackPanel which would solve this problem, unfortunately Silverlight doesn't have this element.
+1 for using the Silverlight DataGrid in this scenario, make sure you have the latest version installed as the default Silverlight SDK version has a few bugs.
Another option is to use the free Silverlight DataGrid Control available here. One of it's features is also a Virtual StackPanel Row Container which means the grid can handle an unlimited number of rows.
Compare the performance of each and see which works best in your situation.
Just an observation - it looks like this is not an issue anymore with Silverlight 4. Adding 100K elements to a data-templated list box is instantaneous and it renders just fine as well.
This helped me: Silverlight DeferredLoadListBox .
It is written by David Anson, a Microsoft employee.
The DeferredLoadListBox derives from ListBox but has much better performance.