Skip to main content
Participant
June 27, 2010
Question

AdvancedDataGrid -> performance problems and possible enhancements

  • June 27, 2010
  • 1 reply
  • 4130 views

We have a very large flex 3 application and are finding that the AdvancedDataGrid doesn't perform well for us. On occasion if you resize a column it can take upwards of 7 seconds (freezing inbetween). I have done some tests and played with the AdvancedDataGrid source to identify some problems. I think I've found some areas that can be improved but I wanted to share my proposed solutions first here to see if anybody had any other ideas or suggestions.

I believe in particular our problems are due to a few things:

1. Grouped Columns - A large number of grouped columns with horizontal scrolling enabled - the grid renders all offscreen columns when there's groups.

2. No Horizontal item renderer reuse - When scrolling horizontally, itemRenderers are not reused - even if columns are using the same itemRenderer factory

3. VariableRowHeight - setting variableRowHeight to true on the grid (understandably) causes each itemRenderer to be rendered for all columns and the row height measured

4. Accessing data too frequently - this one is specific to us as we're using inefficient relational data with dot notated resolving - ie <mx:AdvancedDataGridColumn dataField="building.floor.desk.name" /> which resolves on the fly - each column (visible or not) gets rendered and .data= is called at least twice (for the first row double that for measurement)

I've gone into more detail on my findings below:

1. Grouped columns

We have a paged grid with 42 columns in total with about 7 columns per group and scrolling enabled. The problem is while the grid is designed to reuse item renderers when scrolling vertically - when scrolling horizontally as there are column groups every column is pre-rendered.

I've delved into the source code and have found the following:

- in AdvancedDataGrid.getOptimumColumns() there's an if statement:

if (rendererProviders.length > 0 && horizontalScrollPolicy != ScrollPolicy.OFF || columnGrouping)

     return displayableColumns;

changing this to remove the "columnGrouping" check does prevent all the offscreen columns from being rendered but then they're not drawn when scrolled - I believe I'd be able to fix this with a little digging

2. No Horizontal item renderer reuse

Assuming I've fixed point 1 - then as you scroll horizontally - the columns would need to re-use item renderers to take full benefit - scrolling horizontally is much jerkier than vertical scrolling.

I feel the code to store the free item renderers could be abstracted a little. Currently to extract a free item renderer you must access the dictionary of columns, then itemrenderer factory, then array as follows:

if (freeItemRenderersTable

                && freeItemRenderersTable[factory]

                && freeItemRenderersTable[factory].length)

        {

            renderer = freeItemRenderersTable[factory].pop();

        }

This code is repeated throughout the AdvancedDataGrid and Base and BaseEx

I've moved this into an AdvancedDataGridItemRendererCache class which can be called like so:

var renderer:IListItemRenderer = freeItemRendererManager.getItemRendererForColumn(c, factory)

This then means I have a single place to choose whether or not to access the column first in an internally stored data structure. Changing this indeed means that itemRenderers are reused horizontally - this seems to work except for in hierarchical collections where the indentation is slightly wrong for centered columns. Again I think I'd be able to fix this with some digging.

3. VariableRowHeight

It is understandable that every column for a row must be measured to correctly determine the height of the row. In general I feel it's sensible that this needs to occur. However, for a situation such as mine where this is impeding the performance of the datagrid - I can easily and efficiently extract the height for each row without having to measure each column (as I as a user of the AdvancedDataGrid know my data structure). Therefore if the rowHeight measuring were abstracted into an interface I could handle this myself outside of the grid logic and efficiently return the value - this would save 42 columns from being unnecessarily set.

something along the lines of:

interface IAdvancedDataGridRowHeightMeasure

     public function measureRowHeight(rowData:Object):Number

4. Accessing data too frequently

Again I reiterate that this may be better handled elsewhere - but as the dataFields of our dataProvider is sometimes more than a simple property - repeated access exacerbated the slow performance. Calling the dataField property of a dataProvider multiple times could be made more efficient by caching the value. I could quite easily "flatten" my relational data before it gets to the grid but seeing as this would be an extra step of code - enabling a cache of the dataField - dataProvider values would be fairly straight forward? In addition as the row is redrawn when the collection is updated - the cache could be recreated at that stage.

If anybody has any other suggestions / comments - I'd like to begin making the changes to the AdvancedDataGrid and submitting a patch to the source if anybody thinks the above changes might be useful? Also - if I'm likely to encounter any difficulties in attempting these changes when I could be better improving the grid in another way please let me know.

Also, how different is the grid in flash builder 4 - it's currently not possible for us to upgrade in the short term. I may have time to put the patches into flash builder 4 however.

thanks

Alex

This topic has been closed for replies.

1 reply

Participant
August 25, 2010

Hello,

We have just arrived to the same conclusions about AdvancedDataGrid and GroupedColumns...

When we use "groupedColumns" instead of "columns", all the cells of the visible rows are rendered during vertical scrolling, which make it very slow for large set of columns.

I didn't find any related bug on https://bugs.adobe.com... ? (there are bugs on performance/datagrid/scroll, but none about this particular fact: using groupedColumns makes all the cells rendered during scrolling)

Did you manage to fix it by overriding some parts of the AdvancedDataGrid code ?

Thanks.

Sylvain

Participant
August 30, 2010

Sylvain,

I got a fair way through making some optimisations but got stuck at makeRowsAndColumns which is written for row rendering only not column rendering - so we're going to need to rewrite this function in order to get it to work properly. There's a lot of undocumented code in there and lots of quirks like global variables.

We're currently upgrading to flex 4 so if we do make changes to the AdvancedDataGrid we can submit them back for everyone.

This will be over the next few months

Participating Frequently
May 16, 2011

Folks, we're trying to address some of the issues that many of you are encountering with the ADG performance and such within our new product, Flexicious Ultimate. Although we realize that a commercial third party component may not be an ideal fit for everyone, it would be nice to hear from you as to what kind of use cases/requirements you are trying to accomplish. We've just helped one of our larger customers implement a DG with aroud 1000 grouped columns with smooth horizontal and vertical scrolling and excellent performance.

If you have screen mockups/use cases that you would like to share with us, please feel free to contact us.

===============================

Flexicious - The MUST Have Flex DataGrid

http://www.flexicious.com