Thursday, July 30, 2009

Flex : How expensive pretty looking DataGrids are?

In software world - especially while thriving on Rapid Application Development, people start with prototype development. Under the influence of re-usability - developers land up using the same prototype to build the application framework. At this point in time - probably none would have anticipated the scalability and the volume of data. A small application works like grand-ma and end users get pissed!


Whole gamut of changes has brought the Flex DataGrids to work very slow for an intranet based application.


We ran into this classic case of short-sighted-ness in recent past. Clients came to us frustrated about "performance" of Flex DataGrid implementation in various modules in our application.


While analyzing - we realized that
  1. there were way too many containers used in hierarchical fashion in the layout
  2. Data Grids were using labels for displaying the data and applying dynamic styling
  3. Item Renderer implementation of Labels was such that it would cause
  4. Large amount of data was being transferred over XML from server to the client application

Let's take an example of each of them:

1) Too many contain hierarchies
The way flex layout and children component display works is by applying algorithms to determine x, y position and preferred size and styling. When a flash player runs out of a browser - it is at mercy of memory allocated to browser instance. The more it has to do with limited resources, the more time it will take i.e. degraded performance.


2) Labels as Item renderers in data grids
Think about it from a different perspective. We have a data grid with 45 rows and 28 columns. Based on the display region out of 1260 - required number of label objects will be initialized. The re-draw logic on flex display may invoke various methods on all these object instances even on a mouse move! Even if the execution time for each of them is in milliseconds, multiply it with number of cells visible and you will see how performance degrades.



3) Item renderer implementation

A Label used as ItemRenderer is fine but one has to be mindful of how best to use it? I am sure one cannot call start extending the component by including Label in MXML script and initialize the attribute of Label to cause method calls for colors and text e.g. following declaration may not be a great way to initialize a Label that will be used as itemRenderer.

<mx:Label xmlns:mx="http://www.adobe.com/2006/mxml" color="{(String)(getColorCode(data))}" text="{ getLabelText(data ) }" >


4) Large amount of data transfer between browser and server
Think of a couple of thousands of lines with 38 columns each to be retrieved - be converted to java objects - java objects be converted to XML format - xml be sent to the client - client to parse the xml within memory allocation limits - generate collection of local data types...
There is possibly a scope of improvement 1) to avoid converting the java object to xml and back by switching to binary data transfer and 2) Using a faster data transfer protocols like AMF.

Conclusion:
I would only want to imphasise the importance of giving enough weightage to trivial looking things from beginning and to address the issues in rightest possible way to avoid aging of application and ensuring of scalability.

Tuesday, July 28, 2009

Flex : AdvancedDataGridColumn - problem and solution to make only selected columns editable


Context:

AdvandedDataGridColumn stores list data and stylesheets for AdvancedDataGrid. "editable" is a property of AdvancedDataGridColumn intending to make the column editable or uneditable. When made editable (set editable="true" for the AdvancedDataGridColumn) the cells in the editable column will allow a user to change the cell values by invoking a user specified or default (text) editor in the cell by pressing F2 or with a single mouse click on the cell.

When set a column in AdvancedDataGrid implementation; a user while navigating thru the grid using keyboard will be able to press F2 key and make the cell editable just like Microsoft Excel.

Flex developers will not realize the issue till the time requirement is around implementing something simple. The moment one has to make only selected columns editable; the problem will surface up.

The problem:
When pressed F2 when the datagrid cell is selected, irrespective of editable propertly set to false, column will become editable.
This issue is acknowledged by Adobe Fex but still waiting to be fixed at Adobe's end. Take a look at following URL for more details on this issue - http://bugs.adobe.com/jira/browse/FLEXDMV-2084

Solution at High Level:
My approach to solution was to utlize the event propagation to intercept the keyboard event and hoook my validation to decide if the event should be prevented or allowed.

1. Trap the keyboard event on AdvancedDataGrid
2. Validate if the column isEditable
2.1 if yes: let the control flow thru the business logic to update the cell
2.2 if no: prevent the event propagation further

Implementation Details:
I would want a custom function to be invoked before making the cell editable.

AdvancedDataGrid allows this by letting you specify method name as value of itemEditBeginning attribute in AdvancedDataGrid declaration.

It might look something like this:

validateColumnEditability(event)" selectionMode="multipleCells" editable="true" />

Implementation of validateColumnEditability() might look something like:

public function validateColumnEditability(event:AdvancedDataGridEvent):void
{
if(event.dataField == "allowedCol1" event.dataField== "allowedCol1" ...)
{
//this will return the control and make the column editable
return;
}
else
{
//This will prevent event from being propagated thru the stack
event.preventDefault();
}
}

Further Improvements:
The list of the editable can be made a collection and performing look up on the collection would be much easier / better than string coparison
The function can be coded in utility class as static function (this will require you to import the utility class and invoke this static method.

Please note:
Above code defines the approach to fix the problem and not the best way to code


Monday, July 27, 2009

Flex : Advanced Data Grid - The solution to Keyboard Navigation

Context:
We were in the process to achieve keyboard navigation using Flex on DataGrid. The DataGrid would contain editable and non-editable cells. The proof of concept (POC) started when Flex Builder 2.0 was the only version available.

The proof of Concept:
We figured out working with keyboard event and synchronizing the data and itemEditors would require us lot more effort to come up with a generic component which will not be full proof despite all the testing.

The next step:
The features of Flex 3.0 were released around that time which provided us with a hope. Flex was releasing AdvancedDataGrid and single cell selection was one of the features. We decided to use wait for Flex 3.0 and use AdvancedDataGrid for this implementation.

The pros:
Grouping functionality is great and works wonders with multi level grouping
Allows single cell and multiple cell selections
Objective hierarchy is simple - all the components have a parallel implementation with "Advanced" prefixed. e.g. DataGridColumn and AdvancedDataGridColumn

The cons:
A parallel implementation was required in our code for all the components referring to DataGridObjects as AdvancedDataGrid and DataGrid components do not share the common parent.
For being a Java Developer - it makes life difficult if one cannot utilize polymorphism.
Known bugs required us to take work around way for being early implementers e.g. http://bugs.adobe.com/jira/browse/FLEXDMV-2084

Lessons Learnt:
There are bugs still being fixed in the released component e.g. possible memory leak and single cell selection mode not working in editable mode when some columns are editable and some are not.

Conclusion:
Despite known issues - its great to have a keyboard friendly flex component available. I am sure Adobe will look into making the component more stable and introduce more features with its gaining popularity