Improving Flex application performance using the Flash Player cache

来源:互联网 发布:pb跑步软件 编辑:程序博客网 时间:2024/06/05 00:09

First impressions mean a great deal. The first thing someone does when using an application is to download it—and if that process takes too long, it will detract from the user experience. To improve that experience, you need to learn strategies for reducing the download time and improving the startup time of your Flex applications.

This article shows you how to take advantage of the new Adobe Flash Player cache using Adobe Flex 3. I take a look at how to use this approach in both Flex Builder and the Flex SDK command-line tools.


Requirements
 

In order to make the most of this article, you need the following software and files:

Flex Builder 3

Flex 3 SDK

Flash Player

 


Prerequisite knowledge

 

This article assumes you have some prior experience creating Flex applications using either Flex Builder or the Flex SDK command-line tools.

 


Working with the Flash Player cache

 

The Flash Player cache is a new feature available in Flash Player 9 Update 3 (9,0,115,0). The cache allows files signed by Adobe to be cached by Flash Player. These files end in the file extension .swz.

The Flash Player cache differs from the browser cache in some useful ways. Because the cached SWZ files are signed by Adobe, they can be reused in more than one domain and are not limited to reuse within the domain in which they originated. For example, imagine that framework.swz is loaded from http://www.a.com and is placed in the cache of Flash Player. If the same framework.swz file needs to be downloaded from http://www.b.com, Flash Player looks in its cache to find a.com's framework.swz file. When it finds a match, it uses the cached file rather than loading a new file from b.com.

The SWZ file persists in the cache even after the browser is closed. The file remains in the cache indefinitely, provided that the end user does not change settings in the Flash Player Settings Manager to reduce their caching ability. However, future SWZ files may eventually cause older, unused SWZ files to cycle out of the cache when the cache size limit is reached.

Fortunately, you need only one copy of a framework, since Flash Player uses a common cache for all browsers on a system. This means that if a user downloads a SWZ file using Microsoft Internet Explorer, that same SWZ file will also be available in Mozilla Firefox.

Flex 3 is the first technology to take advantage of the Flash Player cache. In Flex 3, the framework library code has been rolled into Runtime Shared Libraries (RSLs). An RSL can be either a SWZ file or a SWF file that is loaded at runtime instead of being statically linked into the application. Because of this, the application's file size becomes smaller.

A developer can still choose to use unsigned RSLs, which are normal SWF files that are not loaded into the Flash Player cache. Instead, these RSLs rely on the browser's cache to keep them from being downloaded multiple times.

Once the Flex-signed RSLs are cached on a user's machine from running one application, they are available for use by all other applications, regardless of the original domain used to load the application. As Flex applications start using signed RSLs, they will all be able to benefit from the RSLs loaded in the Flash Player cache with lowered bandwidth costs and faster Flex application startup times.

 


Understanding RSL basics

 

In this section I describe the information you'll need to specify a Runtime Shared Library (RSL) for Flex 3. The information includes references to two types of files: SWC files and cross-domain policy files. SWC files are Flex library files that contain one or more components implemented in MXML or ActionScript. All Flex library files are shipped as SWC files in the frameworks/libs directory. A cross-domain policy file is an XML file that provides a way for the server to indicate that its data and documents are available to SWF files served from other domains. Any SWF file that is served from a domain that the server's policy file specifies is given permission to access data or assets from that server.

To create an RSL for Flex 3, you need to include three pieces of information:

  • Pathname of the SWC file
  • URL of the RSL
  • URL of the cross-domain policy file.

Once you have the information, you can choose to enter it in the Flex Builder GUI, in a configuration file, or on the command line.

If there is a problem loading an RSL, failover RSLs may be provided, so the RSL's URL and the policy file may be repeated. The most common reason to use a failover is for the case where a copy of Flash Player prior to version 9,0,115,0 is unable to download a SWZ, so a SWF file is provided as a failover. Another scenario that may warrant using a failover is when the RSL is located on a different server from the application and that server is not responding. Using a failover RSL, you can load the RSL from a different server.

The path of the SWC file is needed for two purposes. The first is to read the digests of the RSLs that are stored in the SWC, which will later be used for validating the cached framework. The digests used in Flex 3 are created using the SHA-256 hash, a standard encryption algorithm.

An RSL digest is taken from the SWC and compiled into the application. After the application reads an RSL from the network or local machine, it checks the digest to compare it against the expected digest stored in the application. If the two digests do not match, the RSL is not loaded into application memory and an error is displayed. The other reason for specifying a SWC is to ensure that all the classes in the SWC can be automatically excluded from the application as it is compiled, which reduces the application's file size.

The RSL URL and the policy file are specified in pairs. However, if you're entering the information on the command line, a policy file does not need to be specified in the last pair if no policy file is required to read the RSL.

Flex 3 comes preconfigured with the SWC library file (framework.swc) ready to be used as an RSL. The file framework.swc contains the code for the Flex framework and the components. To use it you just need to "flip a switch." This process is covered later in this article in the section, Specifying RSLs on the command line.

The flex-config.xml file is located in the sdk_install_dir/frameworks directory. Open it now and look at how it is configured:

<runtime-shared-library-path>
   
<path-element>libs/framework.swc</path-element>
   
<rsl-url>framework_3.0.0.477.swz</rsl-url>
   
<policy-file-url></policy-file-url>
   
<rsl-url>framework_3.0.0.477.swf</rsl-url>
   
<policy-file-url></policy-file-url>
</runtime-shared-library-path> 

The <path-element> element specifies that framework.swc is the SWC to use. The <rsl-url> element specifies the URL of the RSL to load. The name of the RSLs vary based on the build in which they are created. In this example, the RSL is local but theoretically it could be located on another domain. If the RSL is located on another domain, you may need a cross-domain policy file to gain permission to read the RSL. By specifying a policy file, you don't need to rely on the default location of the policy file in the server's root. This allows a policy file to be located in a subdirectory that will limit the scope of the policy file.

The next element is another <rsl-url>, a failover RSL. This one specifies a different RSL to load in case the first RSL is not successfully loaded. If the primary RSL file loads successfully, the failover RSL will not be loaded. Notice that the unsigned RSL is set as the failover for the signed RSL. If the version of Flash Player being used to run the application is not able to load signed RSLs, the signed RSL is skipped and an unsigned RSL is loaded instead. This ensures the application will still be able to load the RSL even if Flash Player 9,0,0,115 or later is not being used.


Using RSLs with Flex Builder

 

You can start using Flex 3 RSLs at any point in the development cycle of your application. Either develop the application using RSLs from the beginning or implement them at the end after the application is done.

Creating a sample program

Let's create a Flex project with a simple "Hello World" program (see Figure 1). Here is the source:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
   
<mx:Label x="165" y="10" text="Hello World"/>
</mx:Application> 

Figure 1. Flex "Hello World" program

In order to reduce the download time, it is helpful to compare the size of your application before and after using RSLs. By default, Flex Builder adds debugging information to SWF files, so in order to see the true size of the application, turn off the debugging information. To do this, add -debug=false to the Additional Compiler Arguments section of the Flex Compiler Properties dialog box (see Figure 2).

Figure 2. Turning off debugging information

Paste the source code for the "Hello World" app into a Flex application file and save it. Check the size of the application by viewing the properties of the application's SWF file created in the bin directory. You can view the properties of a file by right-clicking the file (Option-clicking on Mac OS) and choosing the Properties option in Windows (Get Info on Mac). The size of the application SWF file for the "Hello World" project is 152,269 bytes or about 149K (your result may vary).

Reducing the application SWF file size

Now let's see how you can reduce the size of this application SWF file by pulling the Flex framework code out of the SWF and loading it at runtime as an RSL.

To change how the Flex framework is linked, modify the build properties of the project. First, access the project's properties by selecting the project name in the Navigator View and choosing File > Properties. Next, choose the Flex Build Path properties and click the Library Path tab (see Figure 3).

Figure 3. Changing how the Flex framework is linked in the Library Path dialog box

In the Framework Linkage pop-up menu, change the link type from "Merged into code" to "Runtime shared library (RSL)." Click OK to save the changes. If the option "Project - Build Automatically" is set, your project will be recompiled. If not, you'll need to manually rebuild the project. After recompiling, the size of the application SWF file is reduced to 47,466 bytes (46K), a savings of 104,803 bytes (103K) compared to the SWF that statically links the Flex framework.

You can easily switch between a statically linked application and a dynamically linked application just by toggling the option in the Framework Linkage pop-up menu from "Merged into code" to "Runtime shared library (RSL)." You may want to switch back to "Merged into code" periodically in order to debug code in one of the framework RSLs, because when you choose the option to use RSLs, all of the debug information is removed.

The framework RSL is the only RSL that is configured by default in the flex-config.xml file because every Flex application uses over 100K of framework classes. If you do add RSLs, the compiler will always load any RSLs you specify whether or not they are used by your application.

Adding and changing the linkage of a SWC file

For this example I'll change the linkage of the SDK library rpc.swc. Normally you would do this only if your application uses classes from rpc.swc.

To change the linkage, access the project properties (File > Properties), choose the Flex Build Path, and select the Library Path tab. Make sure the Framework Linkage pop-up menu is set to "Runtime shared library (RSL)." Click the SDK folder to open it up and then open the rpc.swc entry. Next, click the "RSL URL" entry (see Figure 4).

Figure 4. After setting the framework linkage to RSL, drilling down inside rpc.swc to edit the RSL URL options

While RSL URL is selected, click the Edit button to add RSL information for rpc.swc (see Figure 5).

Figure 5. Library Path Item Options dialog box

Select the option to "Use same linkage as framework." This means rpc.swc will use whatever link type is set in the Framework Linkage pop-up menu.

Now click the "Digests" radio button to use Flex 3 RSLs. (If you want to use the RSLs as supported by Flex 2.0.1, choose None.) After selecting Digests, a table with an Add button appears below the radio buttons. Click the Add button to add an RSL URL (see Figure 6).

Figure 6. Specifying the URL of the RSL in the dialog box

A signed RSL is displayed by default. Click OK. After making these changes, the Library Path Item Options dialog box is updated (see Figure 7).

Figure 7. Final settings after making changes to the Library Path Item Options dialog box

Notice the message that appears at the bottom of the dialog box. Because we've specified only a signed RSL, a version of Flash Player that knows how to load RSLs signed by Adobe is required to run the application. The informational message in Figure 7 reflects a known bug in the release. The message says, "This projects settings will be changed to require Flash Player {0}." The message should say, "This project's settings will be changed to require Flash Player 9,0,60." Flash Player 9,0,60 is the earliest version of Flash Player that can load signed RSLs. To allow the application to run in previous versions of Flash Player, add an unsigned RSL as a failover. At runtime, if the version of Flash Player running the application is earlier than version 9,0,60, then the signed RSL will be skipped and the unsigned RSL will be loaded. Since Flash Player 9,0,60 is a beta version, if you need to require a Flash Player version that knows how to load signed RSLs, you should require Flash Player 9,0,115—the latest release as of this writing.

Let's do this now. Click the Add button to add an unsigned RSL. When the dialog box opens, the default URL will be a signed RSL again. All you need to do is change the extension from ".swz" to ".swf" (see Figure 8).

Figure 8. Specifying an unsigned RSL by changing the file extension to .swf

Click OK. After adding the unsigned RSL, the Library Path Item Options dialog box is updated (see Figure 9).

Figure 9. Library Path Item Options dialog box updated after adding the unsigned RSL

Notice that after supplying the project with an unsigned RSL as a failover, Flash Player version 9,0,115,0 is no longer required. The RSL for rpc.swc is now properly configured.

 


Using RSLs with the Flex SDK

 

For this example you'll use the same source file, main.mxml, but this time compile it with the command tool, mxmlc. Because you'll be running a Flash application from the local file directory, make sure the directory you are creating for the application is listed in a Flash Player trust file.

Trust is required because the application needs to read an RSL which (for this tutorial) is a local resource. By default, Flex creates applications that run in the local-with-network sandbox, which aren't allowed to access local files. You didn't need to worry about this in the previous Flex Builder section because Flex Builder added your project directory to the trust file for you. You can configure your trust directory by using the Global Security Settings panel in the Flash Player Settings Manager. If you don't have the trust files set up properly, you will get an error like this one when you run the application:

 

SecurityError: Error #2148: SWF file 
file:///C|/tests/helloworld/main.swf cannot access local resource 
file:///C|/tests/helloworld/framework_3.0.0.477.swz. Only local-with-filesystem and trusted local SWF files may access local resources. 

As in Flex Builder, flex-config.xml is preconfigured with RSL information for framework.swc. To use the configured RSL information from flex-config.xml or other configurations files, you can use the -static-rsls option. The -static-rsls option is an easy way to switch between static linking and dynamic linking using RSLs. The setting -static-rsls=false enables all the -runtime-shared-library-path options that are found in configuration files, while -static-rsls=true ignores them all and statically links the application. The exception to this rule is if the -runtime-shared-library-path option appears on the command line, then it will not be ignored.

Now let's change the directory where you created your main.mxml source file. Enter the following at the command line:

>mxmlc main.mxml  -static-rsls=false 

This line will dynamically link main.mxml using the framework RSL information in flex-config.xml. You can tell the application is linked using an RSL because the size of main.swf is under 50K. Forgetting to copy the RSLs to the application directory is a common mistake. I won't copy the RSLs, so we can see what happens.

Please note that if framework_3.0.0.477.swz already exists in the Flash Player cache, you won't get an error because the RSL will be pulled from the cache instead of being read from the URL. If you want to play along with this part, remove all the RSLs from the Flash Player cache by using the Global Storage Settings panel in the Flash Player Settings Manager. Uncheck the option to "Store common Flash components to reduce download times" and click the Confirm button. Then click the "Store common Flash components to reduce download times" check box again to re-enable the cache.

After doing so, when you run main.swf, it displays the following error (see also Figure 10):

Error #2032: Stream Error. URL: file:///C|/tests/helloworld/framework_3.0.0.477.swf

Figure 10. If the RSLs are not cached or copied to the application directory, an error appears

If you are using the debug version of Flash Player, you will see this message. If you are using the release version of Flash Player, you will see the same error code but without the corresponding error text.

Let's take a look in the log file to see what happened. Beginning with Flash Player 9 Update 3, you cannot modify the log file location or name. The filename is flashlog.txt and its location is hard-coded, depending on your operating system. Table 1 lists the flashlog.txt file locations.

Table 1. Locations of flashlog.txt

Operating system Log file location Windows 95, 98, ME, 2000, XP C:/Documents and Settings/username/Application Data/Macromedia/Flash Player/Logs Windows Vista C:/Users/username/AppData/Roaming/Macromedia/Flash Player/Logs Mac OS X /Users/username/Library/Preferences/Macromedia/Flash Player/Logs/ Linux /home/username/.macromedia/Flash_Player/Logs/

After you've located the log file, open it up. It should look something like this:

Error #2032: Stream Error. URL: file:///C|/tests/helloworld/framework_3.0.0.477.swz Failed to load RSL framework_3.0.0.477.swz Failing over to RSL framework_3.0.0.477.swf Error #2032: Stream Error. URL: file:///C|/tests/helloworld/framework_3.0.0.477.swf 

The first error states that framework_3.0.0.477.swz could not be found. Because there is a failover unsigned RSL configured in flex-config.xml, the application attempted to load framework_3.0.0.477.swf. But that file was not available either. After copying the RSLs to the same directory as the app and running it again, everything works as expected.

As we did with Flex Builder, let's add the rpc RSL—even though our application is not using any classes from this SWC—just to demonstrate how it is done.

You have a couple of options to choose from when configuring the RSL information. You can either use a configuration file or add the command to the command line. Following is an example of each method.

Specifying RSLs in configuration files

This example uses an application configuration file, main-config.xml, whose name is the same as the application but with "-config" appended. This file is automatically read by the compiler at compile time. If I didn't name the file after the application, it would be necessary to use the -load-config option to get the compiler to use the configuration file. First I create the initial contents of main-config.xml by copying the RSL information from flex-config.xml. Then I modify the code from there. Here is the configuration file:

<?xml version="1.0"?>
 
<flex-config>
    
<runtime-shared-library-path append="true" >
      
<path-element>c:/flex_sdk_3_beta3/frameworks/libs/rpc.swc</path-element>
      
<rsl-url>rpc_3.0.0.477.swz</rsl-url>
      
<policy-file-url></policy-file-url>
      
<rsl-url>rpc_3.0.0.477.swf</rsl-url>
      
<policy-file-url></policy-file-url>
   
</runtime-shared-library-path>
 
</flex-config> 

Take special note of the append=true on the runtime-shared-library-path begin element. This causes the entry to be appended to any existing RSL entries in other configuration files instead of overwriting them. From the command line, enter the same command as you did last time. Only this time, rpc.swc will be dynamically linked:

>mxmlc main.mxml –static-rsls=false 

You can verify that the RPC RSLs are linked to the application correctly by running the application without copying the RSLs. You will see errors as before when the application attempts to load the RPC RSL.

If you later decide you want to statically link the application so you can debug the Flex framework code, just set -static-rsls back to true or leave it off the command line all together—since the value defaults to true.

Specifying RSLs on the command line

To link RSLs on the command line, use the -runtime-shared-library-path option. To get help for compiler options, enter mxmlc –help list details at the command line. The output for the -runtime-shared-library-path option is as follows:

-runtime-shared-library-path [path-element] [rsl-url] [policy-file-url] [rsl-url] [policy-file-url]     alias -rslp      (repeatable) 

The first argument of the option is the path of the SWC file (or an open directory that represents a SWC). The next argument is the URL of the RSL that will be used to load the RSL at runtime, followed by the policy file URL.

More than one SWC can be used as an RSL. This is done by adding a -runtime-shared-library-path option for each library. Here's an example of a command that specifies two RSLs:

>mxmlc main.xmml -runtime-shared-library-path=c: lex_sdk_3_beta3 rameworkslibs ramework.swc,framework_3.0.0.477.swz,,framework_3.0.0.477.swf -runtime-shared-library-path= c: lex_sdk_3_beta3 rameworkslibs pc.swc,rpc_3.0.0.477.swz,,rpc_30.189225.swf

This example loads the framework RSL followed by the rpc RSL.


Examining the RSL load order

The order in which RSLs are specified in Flex Builder or on the command line matters. A loaded RSL must not have any classes undefined. If there are undefined classes, Flash Player throws a VerifyError. Let's look at what would cause an RSL to have external dependencies and how to control the load order in Flex Builder and the command line.

An RSL is, in the simplest case, the library.swf pulled from a SWC. It represents the collection of classes in the SWC. If the SWC is built with the -external-library-path option, then that SWC will have external dependences. For example, datavisualization.swc (not part of the free SDK) is built with framework.swc on the external library path (-external-library-path+=libs/framework.swc). Making framework.swc an external library reduces the size of datavisualization.swc because it does not contain any of the framework.swc code it requires. When you statically link an application using datavisualization.swc, you don't have to think about external dependences because framework.swc is on the library path (-library-path). Therefore its classes are available at compile time and are linked into the application automatically.

Now let's say your application is working while statically linked and we decide to link datavisualization.swc as an RSL. When the applications runs, you get a VerifyError loading the RSL. The problem is that datavisualization.swc is dependent on framework.swc. It follows that the datavisualization RSL is dependent on the framework RSL. The application loaded the datavisualization RSL but not the framework RSL. The framework RSL not only needs to be loaded, but it must be loaded before the datavisualization RSL. That way, when the datavisualization RSL is loaded, all of the classes it needs from the framework RSL will be available.

How can the RSL load order be controlled? In Flex Builder, the order of the SWCs in the Library Path tab controls the RSL load order (see Figure 11) .

Figure 11. Load order dictated by the ordering used to list the RSLs in the Library Path tab

To change the load order, select a SWC and then use the up and down buttons to change its location in the list. When using the command line, the order of the -runtime-shared-library-path options controls the load order of the RSLs.


Where to go from here

You should now be able to use RSLs to reduce the size of your applications by using the Flash Player cache to persist the Flex framework RSLs. Try using the Flex RSLs in your applications and see how much download time you can save.

To research further and to get more development tips, see the following articles in the Adobe Developer Connection:

原创粉丝点击