The biggest Flex performance danger is yielding to the temptation to use containers randomly. Using too many containers dramatically reduces the performance of your application. This is the number one performance danger that Flex developers succumb to—and luckily it is 100 percent avoidable. The performance penalty occurs because Flex layout containers and their children follow sizing and measuring algorithms that determine x,y positions, preferred sizes, and styles. These calculations are resource-intensive; it is these calculations, coupled with Flash Player drawing complex objects, that cause a noticeable delay when starting a Flex application or when instantiating a new view in a navigator container. One principle dramatically speeds up application startup and interactivity time: Avoid unnecessary container nesting.
A good rule of thumb is to avoid excessive container nesting. At first, you might find it difficult to pinpoint superfluous container nesting. The following describes some of the more common cases of nesting containers and offers useful tips for choosing and using containers.
Below are a few examples of deeply nested code:
<mx:VBox>
<mx:HBox>
<mx:Form>
<mx:FormItem>
.....
...
</mx:FormItem>
</mx:Form>
</mx:HBox>
</mx:VBox>
and
<mx:Grid>
<mx:GridRow>
<mx:GridItem>
<mx:VBox>
<mx:Button />
</mx:VBox>
</mx:GridItem>
</mx:GridRow>
</mx:Grid>
When you nest containers, each container instance runs measuring and sizing algorithms on its children (some of which are containers themselves, so this measuring procedure can be recursive). When the layout algorithms have processed, and the relative layout values have been calculated, Flash Player draws the complex collection of objects comprising the view. By eliminating unnecessary work at object creation time, you give your application a boost and the performance benefits are readily apparent.
Typically, nesting fewer containers provides good results with respect to creation time. If you find yourself nesting many levels deep, re-evaluate your choice of containers. Perhaps you can achieve the same layout with a different layout container in conjunction with style attributes, such as horizontal and vertical alignment, margins, spacers, and gaps. You can use margins and gaps to manipulate the space around controls and between the edge of controls and the edge of their parent containers. You can use spacer objects to fill unwanted space or to push controls around the screen. You can also align controls horizontally or vertically within their container. For example, take a look at the layout in Figure 1.
Figure 1. You can achieve this layout without using a Grid container.
It is tempting to use a Grid container to achieve this layout:
<mx:Grid>
<mx:GridRow>
<mx:GridItem>
<mx:Button label="Visa"/>
</mx:GridItem>
<mx:GridItem>
<mx:Button label="MasterCard"/>
</mx:GridItem>
<mx:GridItem>
<mx:Button label="Diner's Club"/>
</mx:GridItem>
<mx:GridItem>
<mx:Button label="AmEx"/>
</mx:GridItem>
</mx:GridRow>
</mx:Grid>
However, this code is unnecessarily bloated. In fact, you can easily revise the code so that it looks exactly like Figure 1. The following snippet uses less code and results in a faster creation time and a slightly smaller SWF output.
<mx:HBox> <mx:Button label="Visa"/> <mx:Button label="MasterCard"/> <mx:Button label="Diner's Club"/> <mx:Button label="AmEx"/> </mx:HBox>
Steven Webster, an active Flex community member, has an excellent entry in his blog on the dangers of nested containers, as well as tips on how to avoid nesting.
The Flex container classes are relative layout containers that arrange contents on the screen for you. However, the calculations to decipher how big each container and its children are, as well as where to place them, can potentially be resource-intensive. Here are two tips that can help reduce these calculations:
Think of a Grid container as a layout choice already pushing the deep nesting
rule. Grid, GridItem and GridRow are all containers in their own right, although
GridItem and GridRow are only used in conjunction with the Grid container.
You should only use a Grid container when your controls must line up both horizontally
and vertically. Developers often gravitate to the Grid container, because they
see the similarity to the HTML <table> tag. However, as
a Flex developer, you can choose from multiple container choices
to position objects (and some are less resource-intensive to use then others).
This is not true of the HTML world, where <table> is really
the only choice. The following code provides an example of when to use a Grid
container—the controls in the different columns and rows must all line up (see
Figure 2):
<mx:Grid> <mx:GridRow> <mx:GridItem><mx:TextInput text="TextInput"/></mx:GridItem> <mx:GridItem><mx:NumericStepper/></mx:GridItem> <mx:GridItem><mx:TextInput text="TextInput"/></mx:GridItem> <mx:GridItem><mx:NumericStepper/></mx:GridItem> </mx:GridRow> <mx:GridRow> <mx:GridItem><mx:Button label="button"/></mx:GridItem> <mx:GridItem><mx:DateField /></mx:GridItem> <mx:GridItem><mx:Button label="button"/></mx:GridItem> <mx:GridItem><mx:DateField /></mx:GridItem> </mx:GridRow> <mx:GridRow> <mx:GridItem><mx:TextInput text="TextInput"/></mx:GridItem> <mx:GridItem><mx:NumericStepper/></mx:GridItem> <mx:GridItem><mx:TextInput text="TextInput"/></mx:GridItem> <mx:GridItem><mx:NumericStepper/></mx:GridItem> </mx:GridRow> </mx:Grid>
Figure 2. This UI is the perfect candidate for a Grid container.
Some common misuses of Grid containers include the following:
Using the Grid container when you want to left-justify or right-justify controls in the same container (see Figure 3). Developers often try to do this using the following code:
<mx:Grid borderStyle="solid" width="400"> <mx:GridRow> <mx:GridItem horizontalAlign="left"> <mx:Button label="left" /> </mx:GridItem> <mx:GridItem horizontalAlign="right"> <mx:Button label="right" /> </mx:GridItem> </mx:GridRow> </mx:Grid>
However, using an HBox container with a Spacer object to fill unwanted space works the exact same way, as shown in the following snippet:
<mx:HBox borderStyle="solid" width="400"> <mx:Button label="left" /> <mx:Spacer width="100%" /> <mx:Button label="right" /> </mx:HBox>
![]()
Figure 3. You can achieve this left-justify/right-justify layout without a Grid.
Using a Grid container as a child of a Repeater object when alternate mechanisms would work better. Take a look at the Repeater object in Figure 4.
Figure 4. Using a Grid container in a Repeater object to achieve this layout is resource-intensive.
This Repeater object repeats a heavily populated Grid container with labels retrieved from a web-service. Creating just one of these Grid containers would take a noticeable creation time, but repeating this Grid many times is worse.
As your Flex repertoire expands, you will see that there are alternate containers and controls that you can easily customize to meet your needs. For example, you can achieve the layout shown in Figure 4 with a List control and a custom cell renderer. You can use a cell renderer with any list-based component to create custom-formatted cells, and the cells can be different heights. The Flex documentation will have more information and examples on how to create a custom cell renderer. The performance of a List control with a custom cell renderer is spectacularly better than with a repeated Grid container. Or you can use the HorizontalList and TileList controls to create custom controls in an HBox or Tile-like layout. These controls perform very well because they only create elements visible in the initial view and then the user can scroll to see subsequent elements—instantiation time is quicker.