Test the performance of your application early and often. It is always best
to identify problem areas early and resolve them in an iterative manner, rather
then trying to shove performance enhancements into existing, poorly performing
code at the end of your application development cycle. The following subsections
investigate using Runtime Sshared Libraries (RSLs) to improve performance,
as well as
describe two approaches to performance testing your Flex client: using the ActionScript
profiler and using a code snippet that times application initialization. We
also provide a handy solution to time component and data gestures using the ActionScript
getTimer() method. (See also the "Load
Testing Your Flex Application" section in the "Flex
Application Performance: Tips and Techniques to Improving Flex Server Performance" article.)
You can shrink the size of your application's resulting SWF file by externalizing shared assets into standalone files that you can separately download and cache on the client. Multiple Flex applications can load these shared assets at runtime, but each client need only to download them once. These shared files are called Runtime Shared Libraries.
Flex projects that have multiple Flex applications downloaded to the client can leverage RSLs for better performance. More specifically, the time it takes to download a Flex application once the initial RSL has been downloaded is significantly reduced.
However, not all applications benefit from RSLs. The following are examples of Flex applications that might use RSLs for better performance:
Depending on the type of Flex project you are developing, RSLs may or may not offer a performance benefit. Roger Gonzalez, a developer on the Flex team, has a more in-depth article focused on RSLs: "Using Runtime Shared Libraries."
The ActionScript profiler records the time Flash Player takes to perform tasks in ActionScript. Most commonly, you use the profiler to determine how long an ActionScript function or method takes to execute, how often it is called, and how much time is spent executing in its descendant. This helps identify which objects might be taking too long to initialize, or whether there are bottlenecks due to heavy graphics use or poor coding. However, running the profiler adds overhead to the application you are analyzing. This is because the profiler runs with the Flash Debug Player version, which is slower than the release version. Analyze the results returned with the profiler relative to each other, but do not take them as correct absolute times. Running an application in the release version of Flash Player will yield different results when compared to running the same application with the Flash Debug Player version. The Flex documentation has more information on how to install and run the ActionScript profiler. Macromedia Flex Evangelist Christophe Coenraets also has an excellent blog entry on optimizing application performance with the ActionScript profiler.
A more simple approach to performance profiling is to use code to gauge startup time. The following snippet times application initialization time (the time it takes the Application object to create, measure, lay out, and draw all of its children); it does not include the time to download the client SWF, or any of the server-side processing such as checking the Flash Player version, checking the SWF cache, and so on. The following example shows a sample Flex application that, when invoked in a browser, shows a simple form populated with controls, with the time it took to initialize and print a label.
<?xml version="1.0" encoding="iso-8859-1"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml" creationComplete="doLater(this,'doneNow')">
<mx:Script><![CDATA[
var dp = [{food:"apple", type:"fruit", color:"red"}, {food:"potato", type:"vegetable", color:"brown"}, {food:"pear", type:"fruit", color:"green"},
{food:"orange", type:"fruit", color:"orange"},{food:"spinach", type:"vegetable", color:"green"},{food:"beet", type:"vegetable", color:"red"}];
function doneNow()
{
doLater(this, "reallyDoneNow");
}
function reallyDoneNow()
{
timerLabel.text += getTimer() + " ms"
}
]]></mx:Script>
<mx:Form>
<mx:FormHeading label="Sample Form" />
<mx:FormItem label="List Control">
<mx:List dataProvider="{dp}" labelField="food"/>
</mx:FormItem>
<mx:FormItem label="DataGrid control">
<mx:DataGrid width="200" dataProvider="{dp}"/>
</mx:FormItem>
<mx:FormItem label="Date controls">
<mx:DateChooser />
<mx:DateField />
</mx:FormItem>
<mx:FormItem label="Load Time">
<mx:Label id="timerLabel" fontSize="12" fontWeight="bold" text="The application initialized in "/>
</mx:FormItem>
</mx:Form>
</mx:Application>
The first thing is to get a baseline reading of your application startup time. Ensure that you exit all other running applications, verify that you are using the release version of Flash Player, and run the application three times to get three initialization times. The average of these three times is your baseline reading. As you implement performance tuning, confirm that the startup time is indeed getting faster.
This code will also help you see which portion of your application is the slowest and identify whether you can speed it up. To try this, selectively remove parts of your application to see whether the single part's startup time is relative to the entire application's startup time. This iterative process highlights the problem areas of your application. For example, this methodology might show you that View B of your application loads in six seconds out of an overall startup time of twelve seconds. View B is a problem area for which you can drill down into and investigate performance alternatives. This process is simpler than setting up and using the ActionScript profiler, although it yields much less detailed information.
The getTimer() function is a very useful ActionScript function
that returns the number of milliseconds since a Flex client application has
been running in the browser. Attaching getTimer() calls to events
enables you to time component and data gestures. Brandon Purcell, coauthor
of this article and a support engineer at Macromedia, has a blog
entry explaining how to time Flex data service calls using getTimer().