views:

1331

answers:

4

I'm building my first Flex custom component, in Flex 3. It is a data table based on the 'Grid' container class, with a simple text Label in each cell. (DataGrid and AdvancedDataGrid were not appropriate starting points for my needs.) The component works quite well using smallish tables, but I tried stress-testing it using a larger table, and have been disappointed by the results.

The component creation process has some slow spots, but those are in my power to optimize and aren't my primary concern. What worry me more are what appear to be limitations in the Flex framework itself.

This 'large' sample table has a bit over 7000 cells in it. This is largish, but still 1-2 orders of magnitude less than the biggest I need to accommodate. In standard Grid structure, the main portion of the component consists of a Grid with 400 GridRows of 16 GridItems each, plus a few other smaller ancillary Grids.

Once the table renders, I find the following:

  • Mouse-related events are slow to fire. Specifically, I have rollOver/rollOut event handlers registered on each table cell, to let me highlight the cell under the pointer. On a small table, I could move the mouse over the table very quickly, and the highlighting would follow the pointer in real-time. With the larger table, the highlighting is very jerky, changing only about twice per second, skipping over many cells.
  • If I place the mouse cursor over the component and leave it there, my CPU is pegged (one processor core, anyway), and stays that way until I move off of the component, when it drops to idle. My component isn't doing anything at all at this point.

It feels like Flex simply cannot scale to support component trees that are this large. I shudder to imagine how it would behave with 100,000 cells. Perhaps I'm pushing the Grid beyond its intended use, but having an object per table cell doesn't seem like an unreasonable model, and ~14,000 objects in the tree (a GridItem and a Label per cell) seems pretty modest.

I have yet to get useful data out of the FlexBuilder profiler; I'm working on it. For now, my biggest questions are:

  • Am I really pushing the limits of Flex with this modest test?
  • Is my approach to this component completely off-base?

I'm running this on Flash Player 9 under Firefox on WinXP.

+6  A: 

Yes, Flex is not designed to support very large numbers of components, it is well known that you should minimize the number of components and don't use features that you don't need (Eg. DisplayObject instead of Canvas if you don't need the extra functions).

It's unwise to mirror your data exactly with displayed objects. DisplayObjects (and related classes) are relatively heavyweight, and you need to control how many of those you have.

I would say that the scale you're working at, with 1000+ Cells, and an event listener for each one, would definitely reach Flex's limits.

I think you should take a better look at your approach and architecture. I assume you are not displaying all 1000+ items at the same time, perhaps you should use paging and display 100ish with each screen, with previous/next buttons to move on to another page. You could also consider dynamically adding and removing rows using a custom scrollbar, simulating the scroll effect. This is much more complicated to do.

CookieOfFortune
+1  A: 

Without seeing your code and knowing exactly what you're trying to do...it definitely seems like you're pushing the limits of Flex by pushing that much data into the framework all at once.

Keep in mind that the Flash runtime wasn't designed to handle huge applications...but run somewhat light applications inside the browser. It also seems unlikely that your users are going to need to have access to all of those controls all at once.

You could try providing data services (Java, .NET, etc.) to drive the data in your application. You would then page through the data so that the framework is only dealing with maybe 200 - 300+ elements at a time.

Justin Niessner
+3  A: 

If you look at any List-based control in the Flex framework, you'll see that they make significant use of item renderers which are recycled. So a DataGrid with 20 rows displayed only creates about 22 renderers and recycles them as you scroll through the list. This is why a DataGrid can hold thousands of records and still have pretty snappy performance. I recommend you check out Peter Ent's series of articles on item renderers and take a look at ListBase/List and some of the related classes to understand how to build something similar:

http://weblogs.macromedia.com/pent/archives/2008/03/itemrenderers_p.html

cliff.meyers
Thanks for the link!
Aron
A: 

In flex, if you using Mouse move event to redraw anything .. You might have experienced very slow rendering .

eg:

this.addEventListener(MouseEvent.MOUSE_MOVE, redraw);

and

public function redraw(anything:Object=null):void{
        //draw something here
            this.graphics.clear();
            this.graphics.lineStyle(3, 0x000000);
            this.graphics.moveTo(startPoint.x, startPoint.y);
            this.graphics.lineTo(endPoint.x, endPoint.y);
            this.scaleTextInput.x = centerPoint.x;
            this.scaleTextInput.y = centerPoint.y;

    }

The Above code results very slow rendering ...

Solution:

Use Event.ENTER_FRAME event instead? Although more resource intensive than the mouse move event, you should receive considerably more updates per second, allowing the mouse to appear more responsive to the user:

Eg:

this.addEventListener(Event.ENTER_FRAME, redraw); instead of

this.addEventListener(MouseEvent.MOUSE_MOVE, redraw);

and You are good to go ..Happy Flexing

More on: http://www.deepakdhakal.com