Archive for January, 2011

as3term – Handy app for compiling AS3 snippets

Friday, January 21st, 2011

I found a cool little Air app on riaspace.com for compiling and executing simple snippets of AS3 code.

Very handy for testing out things like Math functions.

as3term

Flash Builder 4, Flex 3 SDK: Export Release Build Error

Wednesday, January 19th, 2011

Had to import some Flex 3 projects to Flash Builder 4 (using it in work now), and everything seemed to go ok. Had copied the Flex 3 SDK from FB3 folder, set it as the default in FB4. Cleaned and ran the project (including RSL library projects) all ok. Then went to Export Release Build and got:

Error – One or more errors were found while trying to build the release version. Unable to export.

The Log file (thanks to doc_180 on Stackoverflow) showed the cause as:

java.lang.NoClassDefFoundError: flex2/tool/oem/OEMException$CircularLibraryDependencyException

Log file can be found at the equivalent of C:\Documents and Settings\bbishop\Adobe Flash Builder 4\.metadata

Turns out that 3 files are required by Flex 3 SDK to export a release build in Flash Builder 4 where RSL’s (Library projects) are used, and these are missing. Luckily you can copy these from the Flex 4 SDK.

Let me shout out a thanks to eggsWurzel for his Adobe Forum Post with the solution. Bug is on the Adobe Jira Bug Database

How to implement the solution

  1. Get a copy of flex-compiler-oem.jar from C:\Program Files\Adobe\Adobe Flash Builder 4\sdks\4.1.0\lib
  2. Extract flex-compiler-oem.jar (using Winzip/7 Zip/Winrar), and go to the flex2\tools\oem folder in the extracted files
  3. Look for the following 3 files:
    1. OEMException$CircularLibraryDependencyException.class
    2. OEMException.class
    3. OEMException_en.properties.
  4. Open Winrar (doesnt work for me with Winzip or 7 Zip), and in the AddressBar browse to the flex-compiler-oem.jar file in the Flex 3 SDK – should beequivalent to C:\Program Files\Adobe\Adobe Flash Builder 4\sdks\3.2.0\lib (make a copy first just in case), and open \flex2\tools\oem
  5. Drag the 3 OEM files over to the \flex2\tools\oem folder in Winrar

That’s it! Close Winrar, and restart Flash Builder 4, should Export a release build ok now:) Nice one.

Note: if using RSL’s you may also need to untick Use local debug runtime shared libraries when debugging from Flex Build Path>Library Path

App Size: Flex vs Actionscript Project (Flex Framework Caching)

Friday, January 14th, 2011

Following on from discussions at the ‘after’ part of last nights MMUG-Dublin meeting, I created a pure Actionscript 3 project and a similar Flex application project, both in Flex Builder 3. The aim was to compare final swf size. Both apps draw 3 circles on the screen.

Three circles, well done

Size Wise:

Flex 3 Application SWF (Release Build of Project): 169KB (but only 65KB with framework caching – see Optimization section below)

Pure Actionscript 3 Project SWF: 1KB

Optimization – Framework Caching

By default, the flex framework gets merged into your main swf file, adding around 100KB+. This can be avoided by going to Properties/Flex Build Path/Library Path/Framework Linkage/ and selecting Runtime Shared Library (RSL) from the dropdown. When you do a Build Release Project, your framework will be exported as a signed swz and an unsigned swf . These files should be placed in the same directory as your main swf file on the web server. In Flex 4, the framework RSL will automatically point to a public section of the Adobe site, where the swz’s will be available. Saves you having to host them.

The framework will only need to be downloaded by a particular client once, and will be cached by Flash Player, meaning every subsequent use of your app will not require downloading of the framework.swz (in the release will be named something like framework_3.2.0.3958.swz).

Read more about framework caching here: http://ted.onflash.org/2008/01/flex-3-framework-caching.php

Conclusion

If Actionscript will suffice e.g. for drawing three circles on the screen, go with a pure AS3 Project. If your developing data driven applications and user interfaces, use the Flex SDK (saves a tonne of time and effort, and whats 60kb these days – less than most peoples profile pics). Have a look at this Stackoverflow question for more opinions on each approaches pros and cons.

Code

Flex

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
	initialize="onInitialize()">
	<mx:Script>
		<![CDATA[
			import mx.core.UIComponent;

			private function onInitialize():void{
				drawCircle( 0x336699 );
	            drawCircle( 0x993333 );
	            drawCircle( 0x339933 );
			}

			private function drawCircle( color:uint ):void
	        {
	            var circle:Shape = new Shape();
	            var displayObject:UIComponent = new UIComponent();

	            circle.graphics.beginFill( color );
	            circle.graphics.lineStyle( 2, 0xCCCCCC );
	            circle.graphics.drawCircle( 30, 40, 30);
	            circle.graphics.endFill();
	            circle.x = (this.numChildren * 65) + 10;
	            circle.y = 0;

	            displayObject.addChild(circle);
	            this.addChild(displayObject);
	        }
		]]>
	</mx:Script>
</mx:Application>

Actionscript Project

package {
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;

	public class ActionScriptProject extends Sprite
	{
		public function ActionScriptProject()
		{
			stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
            doDrawCircle( 0x336699 );
            doDrawCircle( 0x993333 );
            doDrawCircle( 0x339933 );
		}

		private function doDrawCircle( color:uint ):void
        {
            var child:Shape = new Shape();
            child.graphics.beginFill( color );
            child.graphics.lineStyle( 2, 0xCCCCCC );
            child.graphics.drawCircle( 30, 40, 30);
            child.graphics.endFill();
            child.x = (this.numChildren * 65) + 10;
            child.y = 0;
            addChild(child);
        }

	}
}

Flex application optimization

Wednesday, January 12th, 2011

The following are some of the optimization techniques I used on medium to large projects (reduced load time by up to 30-40%).

1. Module use and optimization:  -link-report, -load-externs

Firstly, creating a modular application reduces initial load times. If its a possibility that the particular views/components that are modularized may not be activated by the user, then their deferred loading is a big plus.

When modules are released or built (using Clean or Project>Export Release Build..), the exported module swf’s will include any Flash/Flex framework classes and external swc/swf classes that are used by the modules.

This is not always optimal, as some of the files included in the Module’s swf’s may already be in used by the Main app, and included in the MainApp.swf. You can remove the overlapping classes from the module swf’s by doing the following:

  1. In your main app i.e. the one that will use the module, go to Project>Properties>Flex Compiler and add an Additional compiler arguments:

-link-report=link_report.xml

  1. Clean or Export Release Build the project.
  2. Copy the link_report.xml file from the bin-debug or bin-release folder and paste it to the root of the module project folder i.e. the same folder as the Module.mxml file(s).
  3. Repeat step 1 for the Modules project, and add the compiler arguments:

-load-externs=link_report.xml

  1. Clean or Export Release Build the project.

The released module swf’s will not include any external files that it shares with the main app. Reduced the size of the module I was optimizing in work by 15%!

Additional Compiler Arguments

More details on the compiler arguments and module optimization from:

http://livedocs.adobe.com/flex/3/html/help.html?content=modular_4.html

Caution: any time you change your main app, and remove or change dependencies or SDK versions, you will need to repeat the above process. The modules will not work with apps that they have not been optimized for.

If you receive an error message -load-externs “could not open …..”, make sure that the xml file is at the root of the module project.

2. Framework Caching

By default, the flex framework gets merged into your main swf file, adding around 100KB+. This can be avoided by going to Properties/Flex Build Path/Library Path/Framework Linkage/ and selecting Runtime Shared Library (RSL) from the dropdown. When you do a Build Release Project, your framework will be exported as a signed swz and an unsigned swf . These files should be placed in the same directory as your main swf file on the web server. In Flex 4, the framework RSL will automatically point to a public section of the Adobe site, where the swz’s will be available. Saves you having to host them.

The framework will only need to be downloaded by a particular client once, and will be cached by Flash Player, meaning every subsequent use of your app will not require downloading of the framework.swz (in the release will be named something like framework_3.2.0.3958.swz).

Read more about framework caching here: http://ted.onflash.org/2008/01/flex-3-framework-caching.php

3. Remove unused class references

Any classes that are referenced in your application (whether they are actually used or not) will be included in the main exported swf. It can be time consuming to remove unreferenced imports and object instances, but it has a two pronged advantage: cleaner code, reduced swf size. When using Library projects (swc files), remember to go to Project Properties>Flex Library Build Path>Classes – untick any classes not needed for the project release.

4. Flash/Flex Builder Profiler

No so helpful for reducing load times, but memory use and memory leak discovery is its main function. The Profiler would need its own dedicated article, but here are a few tips:

  • Using Flash Builder 4? If so, you will need a debug version of Flash Player 10.0.x or less to run the Profiler (problems with FP 10.1)
  • Firefox is shaky with the Profiler (if you can get it to work at all). Reverted to IE with tabs disabled, worked fine
  • If you notice a memory leak, but cannot find the cause, remove any filtering package filtering e.g. mx.*.*, you may spot a UIComponent that isnt being garbage collected
  • On profiler startup, check the Generate object allocation stact trace option – lets you see where target objects were created, and allows you to jump to that code location
  • To find loitering objects, create two memory snapshots (with some UI activity and time in between), select both and click Loitering Objects button. Sort by instances: you may spot an object that is accumulating and not being garbage collected – will show with Path>GC as Yes
  • Major cause of loitering objects is Event Listeners holding references to objects (use weak references or remove listeners before display object is removed from stage), data binding (BindingUtil.bindsetter() is an example), any object instance references that are not disposed of.

5. Managing User Experience (UX)

Probably the most important aspect, but often overlooked by developers, is the UX.

Do you use indeterminate loading bars, is you initial screen blank until the app loading is complete? This can be annoying for user (as you know yourself).  Use determinate % loading bars where possible. Create a custom preloader, maybe with a background image on the screen, or some text (if a user if reading something relevant, or being given some visual stimuli, then impatience caused by the loading process can be somewhat dissipated). Even at the expense of a little extra load time, make the loading process interesting. It’s also the percieved load time we need to address.

Here’s an interesting article with some real-world and online examples of engaging users during loading/waiting: UXBooth.com

Place a full screen image in place of the usual background during loading: http://polygeek.com/2749_flex_display-an-image-in-your-application-preloader

Edit the determinate preloader with custom graphics and styles: http://blogagic.com/14/the-blogagic-custom-flex-preloader

Other

  • Server / Web API calls: one large initial load, or smaller chunks of data more frequently? Very project dependent, but can impact load time via server all delay and data processing on the Flex end
  • Remove rarely used Embedded assets, load these dynamically, especially if they are medium-large image files
  • Compiler option: -debug false