Techniques for Delivering Modular Flex Applications

Day 3. Session 5. Roger Gonzalez really digs into optimizing your large Flex applications. Warning: this one is heavy, folks.

Old-school SWF info: SWFs are organized into a series of frames, and a frame cannot be displayed until it has been downloaded completely. Typical animation is drawing a slightly different version of a graphic on subsequent frames, the last frame then looping back to the first. (or simply moving an asset on each frame using the timeline). This is not very extendable, now is it? What if we want to change our mode while in the middle of the animation? So animations evolved to be code-driven, which allowed physics models, more detailed visuals, etc.

Anyways, all the advance has turned into a much larger set of content being downloaded for a SWF file. Many applications do not need to have all components or definitions available immediately. Thus the need for a modular framework.

To build modular Flex applications, it is first important to reduce or eliminate interdependencies via interfaces.

ApplicationDomain is a box that holds definitions/classes – forms a hierarchy of containers.

If parent Flex applications contain a class definition, any child Flex applications that also get loaded will not re-initialize these classes (by name). This is important considering static classes and also performance. This could also effect security models when loading a child application from another website/domain.

When compiling, you can also exclude external references, or exclude classes to help limit file size and improve download performance.

Soft dependancies can be formed using the ApplicationDomain, and can be resolved by late-loading a SWF containing the definition. Hard dependencies must be satisified in your SWF.

Hard dependencies:
public var howdy:Hello = new Hello);
class Yo extends Hello…
function x(hiya:Hello):void …

Soft dependencies:
var Hello:Class = Class(getDefinition(“Hello”));
var howdy = new Hello();

How to partition functionality?

  1. Reduce dependencies – use interfaces, allows mix-ins that satisfy the same requirement
  2. Satisfy hard dependencies – load a RSL, load into a context where externals are satisfied by a parent ApplicationDomain
  3. Satisfy soft dependencies – [missed the information]

RSL’s (Runtime Shared Libraries) should typically be used if the library is actually going to be used across multiple applications. If you only have one application, the combined file size of the application + RSL will certainly be larger than a single combined SWF. Also, RSL’s have a longer startup time even after the RSL has been downloaded to the client, so analyze your use-case carefully.

Shells & Modules

When loading external SWF’s, the root class of each module SWF should implement an interface that is known to the shell application. Thus the main loaded application can listen for events, or call known functions in the modules. Flex 2.0.1 contains a new package that implements this shell/module model.

Example IModuleInfo interface:
[event] SETUP – fires when initially loaded
[event] READY – fires when the module has finished drawing, and is ready for communication by the containing application
info() – returns simple information
create(params:Object) – does whatever the module would do to build itself out

There are 3 levels of modular API that Roger defines:

Low-Level API: modules implement IFlexModuleFactory (info+create functions)

Mid-Level API: modules extend ModuleBase (compiler generates factory with one product)

High-Level API: application uses and modules are built using

Portal & Portlets model

Is similar to the Shells and Modules above, but you would define your own interface. For example a WidgetContainer might contain:

  • registerWidget(widget:IWidget)
  • unregisterWidget(widget:IWidget)
  • initialize() – actually extends Flex’ component initialize() method
  • render()
  • getWidgetSize()
  • getter: displayObject() – returns the “shape” or other useful expected sub-component

Problem: an application with hundreds or thousands of screens (us!). Startup time and memory use is prohibitive when compiled into a single monolithic application. Users may not even use all these screens. Instead, we can bundle packages of related screens into individual SWF’s using the Shell/Module pattern.

Another approach for embedded assets – use the “published” URL protocol. As long as an asset is guaranteed to be published to a URL from a child module, you can refer to these URL’s in the primary application or other modules.

Tips

Embedded fonts don’t work very well across SWF boundaries due to legacy support. Better support coming in Flex 2.0.1.

ApplicationDomain.currentDomain tracks the location of the code that called it – based on which SWF module contains the class definition you are executing within currently. This can cause some headaches when troubleshooting modular apps.

Check out more information at:
http://blogs.adobe.com/rgonzalez

Tags:» » » »

Post a Comment

Your email is never published nor shared. Required fields are marked *

*

*