Introduction to RSLs

One way to reduce the size of your applications’ SWF files is by externalizing shared assets into stand-alone files that can be separately downloaded and cached on the client. These shared assets can be loaded and used by any number of applications at run time, but are transferred only once to the client. These shared files are known as Runtime Shared Libraries or RSLs.

When multiple applications share a core set of components or classes, clients can download those assets only once as an RSL rather than once for each application. The RSLs are persisted on the client disk so that they do not need to be transferred across the network a second time. The resulting file size for the applications can be reduced. The benefits increase as the number of applications that use the RSL increases.

Applications built with Flex support the following types of RSLs:

  • Framework RSLs — Libraries of components and framework classes that all applications can share. Framework RSLs are precompiled for you. Adobe provides hosted, signed framework RSLs that you can link to from any application that has internet access. For more information, see Using the framework RSLs.

  • Standard RSLs — A library of custom classes created by you to use across applications that are in the same domain. Standard RSLs are stored in the browser’s cache. For more information, see About standard RSLs.

  • Cross-domain RSLs — A library of custom classes, like standard RSLs, with the difference being that they can be loaded by applications in different domains and sub-domains. Cross-domain RSLs are stored in the browser’s cache. For more information, see About cross-domain RSLs.

You can create your own RSLs from custom libraries. You do this by using either the Adobe® Flex® Builder’s™ Build Project option for your Flex Library Project or the compc command-line compiler.

About linking

Understanding library linking can help you understand how RSLs work and how you can most benefit from their use. The Flex compilers support static linking and dynamic linking for class libraries (including RSLs). Static linking is the most common type of linking when compiling an application. However, dynamic linking lets you take advantage of RSLs to achieve a reduction of the final SWF file size and, therefore, a reduction in the application download time.

When you use static linking, the compiler includes all referenced classes and their dependencies in the application SWF file. The end result is a larger file that takes longer to download than a dynamically-linked application, but loads and runs quickly because all the code is in the SWF file.

To statically link a library’s definitions into your application, you use the library-path and include-libraries compiler options to specify locations of SWC files.

When you use the library-path option, the compiler includes only those classes required at compile time in the SWF file, so the entire contents of a library are not necessarily compiled into the SWF file. The include-libraries option includes the entire contents of the library, regardless of which classes are required. You can also use the source-path and includes options to embed individual classes in your SWF file.

In Flash Builder, you use the Project > Properties > Flex Build Path > Library Path dialog to add libraries to your project. To statically link a library at compile time, you select Merged Into Code for the library’s Link Type. This includes only those classes that are used in the application, so it is the equivalent of the library-path compiler option.

If you statically link any part of a library into your application, you cannot use that library as an RSL.

Dynamic linking is when some classes used by an application are left in an external file that is loaded at run time. The result is a smaller SWF file size for the main application, but the application relies on external files that are loaded at run time. Dynamic linking is used by modules, runtime stylesheets, and RSLs.

When you want to use a dynamically-linked library, you instruct the compiler to exclude that library’s contents from the application SWF file when you compile the application. You must provide link-checking at compile time even though the classes are not going to be included in the final SWF file. At run time, the application loads the entire library into the application SWF file, which can result in slower startup times and greater memory usage.

You can use the runtime-shared-library-path (Flex 4 and later) and runtime-shared-libraries (Flex 3) options to specify the location of dynamically-linked libraries.

You can also use the external-library-path, externs, or load-externs compiler options to specify the files to dynamically link into an application. These options instruct the compiler to exclude classes and libraries from the application, but to check links against them and prepare to load them at run time. The external-library-path option specifies SWC files or directories for dynamic linking. The externs option specifies individual classes or symbols for dynamic linking. The load-externs option specifies an XML file that describes what classes to use for dynamic linking. These options are most often used when externalizing assets from modules so that the module and the application do not contain overlapping class definitions. The runtime-shared-library-path option provides all the arguments to use external libraries as RSLs.

In Flash Builder, to use dynamically-linked libraries, you specify either RSL or External as the Link Type in the Library Path dialog for the library.

You can view the linking information for your application by using the link-report compiler option. This generates a report that has the same syntax as the file that you load with the load-externs option, so you can use it as an argument to that option without changing it. For more information about this report, see Examining linker dependencies.

For more general information about the command-line compiler options, see Flex compilers.

RSL benefits

The following example shows the possible benefit of separating shared components into an RSL. In this example, the library’s size is 150 KB (kilobytes) and the compiled application’s size is 100 KB. Without RSLs, you merge the library into both applications for an aggregate download size of 500 KB. If you add a third or fourth application, the aggregate download size increases by 250 KB for each additional application.

With RSLs, the RSL needs to be downloaded once only. For two applications that use the same RSL, the result is an aggregate download size of 350 KB, or a 30% reduction. If you add a third or fourth application, the aggregate download size increases by 100 KB instead of 250KB for each additional application. In this example, the benefits of using an RSL increase with each new application.

In this example, the applications with statically-linked libraries run only after Adobe® Flash® Player loads the 250 KB for each application. With dynamically linked RSLs, however, only the first application must load the entire 250 KB (the combined size of the application and the RSL). The second application runs when just 100 KB loads because the RSL is cached.

The illustrated scenario shows one possible outcome. If your applications do not use all of the components in the RSL, the size difference (and, as a result, the savings in download time) might not be as great. Suppose that each application only uses half of the components in the RSL. If you statically link the library, only those classes that are used are included; the output, as a result, is 100 KB + 75 KB for the first application and the library and 100 KB + 75 KB for the second application and the library, or an aggregate download size of 350 KB. When you use a library as an RSL, its entire SWF file must be transferred across the network and loaded by the application at run time, regardless of how much of that library is actually used. In this second case, the combined download size when using RSLs and when not using RSLs is the same.

In general, the more applications that use a common RSL, the greater the benefit.

RSL considerations

RSLs are not necessarily beneficial for all applications. You should try to test both the download time and startup time of your application with and without RSLs.

Standard RSLs can not be shared across domains. If a client runs an application in domain1.com and uses an RSL, and then launches an application in domain2.com that uses the same RSL, the client downloads the RSL twice even though the RSL is the same. You can overcome this limitation of standard RSLs by using cross-domain RSLs.

Cross-domain RSLs can be loaded by any application, even if that application is not in the same domain. They do, however, require that you create and check a digest when the RSL is loaded. This can increase startup time of the application by a small amount.

Framework RSLs can also be loaded by any application. To take advantage of the fact that framework RSLs can be cached in the Player cache, the client must be running a recent version of Flash Player. Not all clients necessarily have the latest Player, so loading a framework RSL might fail. In these cases, you can specify a failover RSL.

An RSL usually increases the startup time of an application. This is because the entire library is loaded into an application regardless of how much of the RSL is actually used. For this reason, make your RSLs as small as possible. This contrasts with how statically-linked libraries are used. When you compile an application, the compiler extracts just the components it needs from those component libraries.

If you have several applications that share several libraries, it might be tempting to merge the libraries into a single library that you use as an RSL. However, if the individual applications generally do not use more than one or two libraries each, the penalty for having to load a single, large RSL might be higher than it would be to have the applications load multiple smaller RSLs.

In this case, test your application with both a single large RSL and multiple smaller RSLs, because the gains are largely application specific. It might be better to build one RSL that has some extra classes than to build two RSLs, if most users will load both of them anyway.

If you have overlapping classes in multiple RSLs, be sure to synchronize the versions so that the wrong class is never loaded.

You cannot use RSLs in ActionScript-only projects if the base class is Sprite or MovieClip. RSLs require that the application’s base class, such as Application or SimpleApplication, understand RSL loading.

In general, you should disable RSLs when compiling modules, CSS SWF files, and applications that will be loaded as child SWFs in a parent application. The parent application will likely use RSLs and dynamically link the required classes.

About caching

RSLs are cached when they are first used. When they are needed by another application, they can be loaded from the cache rather than across the network. Caching is one of the benefits of RSLs, because disk access is much faster than network access.

The type of caching used by an RSL is based on the type of RSL. Standard or cross-domain RSLs are stored in the browser’s cache. If the user clears their cache, the RSLs are removed and must be downloaded again the next time they are needed. Unsigned framework RSLs are also stored in the browser’s cache.

Signed framework RSLs are stored in the Player cache. This is a special cache that is maintained by Flash Player. To clear this cache, clients must invoke the Settings Manager. RSLs stored in this cache are signed and therefore can be used by any application without the need for a cross-domain policy file.

For more information about the framework cache, see About the Player cache.

Common RSL tasks

The techniques in this section apply to framework and custom RSLs.

Removing unused RSLs

By default, the compiler removes unused RSLs when an application is compiled. This prevents an application from having to download RSLs that it does not use. You can override this behavior by preventing the compiler from removing unused RSLs.

To prevent unused RSLs from being removed, set the remove-unused-rsls compiler option to false. The default value is true.

You can configure the remove-unused-rsls compiler option in the flex-config.xml file, as the following example shows:
<remove-unused-rsls>true</remove-unused-rsls>
In Flash Builder, to toggle the remove-unused-rsls option:
  1. Select Project > Properties.

  2. Select Flex Build Path. The Flex Build Path dialog appears.

  3. Select the Library Path panel.

  4. Select or deselect the “Remove unused RSLs” checkbox.

  5. Click OK to save your changes.

Forcing RSLs to load

You can force the compiler to load particular RSLs when compiling your application. You do this with the force-rsls compiler option.

Forcing RSLs to load can be useful if you use classes that are only referenced indirectly (sometimes referred to as “soft references”), so the compiler might not know they are needed.

When forcing RSLs to load, you must configure them in the runtime-shared-library-path option in addition to specifying them with the force-rsls option.

The following example forces the osmf.swc and rpc.swc RSLs to be loaded:
mxmlc -force-rsls=libs/osmf.swc,libs/rpc.swc MyApp.mxml
You can configure the force-rsls compiler option in the flex-config.xml file, as the following example shows:
<runtime-shared-library-settings> 
    <force-rsls> 
        <path-element>libs/osmf.swc</path-element> 
        <path-element>libs/rpc.swc</path-element> 
    </force-rsls> 
</runtime-shared-library-settings>
In Flash Builder, to force an RSL to load:
  1. Select Project > Properties.

  2. Select Flex Build Path. The Flex Build Path dialog appears.

  3. Select the Library Path panel.

  4. Select the RSL from the “Build path libraries” list and click Edit. The Library Path Item Options dialog box appears.

  5. Select the “Force load RSL” checkbox.

  6. Click OK to save your changes.

Viewing required RSLs

By default the compiler outputs a list of RSLs that an application uses. This is viewable in the command line compiler’s output.

The following is an example of the output from an application that loads the framework, textLayout, spark, sparkskins, and osmf RSLs:
Required RSLs: 
    http://fpdownload.adobe.com/pub/swz/flex/4.6.0/framework_4.6.0.swf with 1 failover. 
    http://fpdownload.adobe.com/pub/swz/flex/4.6.0/textLayout_2.0.0.139.swf with 1 failover. 
    http://fpdownload.adobe.com/pub/swz/flex/4.6.0/spark_4.6.0.swf with 1 failover. 
    http://fpdownload.adobe.com/pub/swz/flex/4.6.0/osmf_1.0.0.16316.swf with 1 failover.

The list of required RSLs displays the expected location of the RSLs at runtime. In this case, the expected location is the signed SWFs available on Adobe’s website. The output also notes that there is a failover location in case the Adobe RSLs are unavailable. You can see this location in the flex-config.xml file.

Note that if static-link-runtime-shared-libraries option is set to true, then no RSLs are listed because they are not used. Static linking is used instead.

Disabling RSLs

You can disable RSLs when you compile your application by setting the static-link-runtime-shared-libraries compiler option to true.

In general, disabling RSLs is useful only when compiling style SWF files, resource bundles, or other non-application assets.

Using RSLs with modules and sub-applications

RSLs are designed to work efficiently with modules and sub-applications. When using RSLs with modules and sub-applications, note that:
  • Main applications only load RSLs that are needed, but create placeholders for the remaining framework RSLs. This lets the module or sub-application load other framework RSLs into the main application when they need it.

  • Sub-applications and modules share framework RSLs by default.

  • Sub-applications and modules can share custom RSLs if you configure the application domain that the RSLs are loaded into.

Using placeholder RSLs

When you compile an application with Flex, the default behavior is to compile the application against the framework (or default) RSLs. When the application runs, it loads only the framework RSLs that it actually uses, and creates placeholders for the remaining framework RSLs. When the application loads a module or sub-application that requires one of the framework RSLs for which there is a placeholder, the module or sub-application then loads that RSL into the main application.

If a module or sub-application requires a framework RSL that is already loaded, it will not load the RSL again. It will instead use the existing RSL.

To ensure that placeholders for framework RSLs are used, set the remove-unused-rsls compiler argument is true when compiling the main application, sub-applications, and modules. This is the default.

By default, framework RSLs are loaded into the top-most application domain that contains a placeholder for that RSL. As a result, modules or sub-applications can share RSLs that were loaded by other modules or sub-applications, as long as you do not restrict the domain into which the RSL was loaded.

Specifying domains for RSLs (advanced)

When loading custom or framework RSLs into a sub-application or module, you can specify the application domain into which the RSL is loaded. You do this with the application-domain compiler argument. This lets you restrict RSLs from being shared, or ensure that they are shared, among modules and sub-applications.

The application-domain compiler argument has the following syntax:
runtime-shared-library-settings.application-domain= 
    path-element,application-domain-target

The path-element option specifies the location of the RSL’s SWC library file. This RSL must also be defined by the runtime-shared-library-path option.

The application-domain-target option takes one the following values:
  • default — Loads the RSL into the top-most application domain with a placeholder. If no placeholder is found, then the RSL is loaded into the current application domain.

  • current — Loads the RSL into the module or sub-application’s current application domain. Modules and sub-applications will not be able to share this RSL with anything other than child modules or sub-applications.

  • top-level — Loads the RSL into the application domain of the top-level SystemManager. This is the main or root application. In this case, all modules and sub-applications will be able to share this RSL.

  • parent — Loads the RSL into the application domain of the parent application or module.

The following example snippet from the flex-config.xml file defines a custom RSL, MyLibrary, and instructs it to be loaded into the top-level application domain:
<runtime-shared-library-path> 
    <path-element>libs/MyLibrary.swc</path-element> 
    <rsl-url>bin/MyLibrary.swf</rsl-url> 
    <policy-file-url></policy-file-url> 
</runtime-shared-library-path> 
<runtime-shared-library-settings> 
    <application-domain> 
        <path-element>libs/MyLibrary.swc</path-element> 
        <application-domain-target>top-level</application-domain-target> 
    </application-domain> 
</runtime-shared-library-settings>

Note that RSLs can only be shared between sub-applications and modules that have a common parent. A sub-application or module cannot share RSLs with a sub-application that is untrusted (sandboxed) or loaded for version compatibility (multi-versioned).

Changing RSL application domains in Flash Builder

To change the application domain of an RSL in Flash Builder:
  1. Select Project > Properties.

  2. Select Flex Build Path. The Flex Build Path dialog appears.

  3. Select the Library Path panel.

  4. Select the RSL from the “Build path libraries” list and click Edit. The Library Path Item Options dialog appears.

  5. Select the appropriate application domain from the Application Domain drop-down box.

  6. Click OK to save your settings.

Preventing framework RSLs from being shared among modules and sub-applications

For framework RSLs, the default is to load an RSL into the highest application domain that has a placeholder for the RSL (typically the main application). The result is that once a module or sub-application loads an RSL, all subsequent modules or sub-applications that need this RSL will not have to load it. The downside to this is that when the module or sub-application is unloaded, the RSL is not unloaded.

To prevent a framework RSL from being loaded into the main application, you can specify "current" for the application domain. This loads the RSL into the module or sub-application’s application domain. When the module or sub-application is unloaded, so is the RSL. Other modules or sub-applications will not have access to it. You should not specify "current" for the application domain when loading the OSMF or MX RSLs. These RSLs are always loaded into the root application.

Sharing custom RSLs among modules and sub-applications

For custom RSLs, the default is to load the RSL into the module or sub-application’s current application domain. The result is that the module or sub-application does not share the RSL with sibling modules or sub-applications, but only with child sub-applications or modules that it loads.

To load a custom RSL into an application domain so that it can then be shared with other modules and sub-applications, you specify "top-level" for the application domain. This loads the custom RSL into the main application. All modules and sub-applications will then be able to access that RSL.

You should ensure that applications or modules do not statically link classes in a custom RSL. If those classes are loaded before the RSL is loaded, then class conflicts can occur when the RSL is loaded. One technique to use when doing this is to ensure that all modules, sub-applications, and the main application share the same RSL definitions. If this is the case, classes will not be statically linked when they exist in an RSL.