Home  >  

Flex RIA Performance Considerations Part 2: Application Startup

Author photo
| | Comments (23)
AddThis Social Bookmark Button

Overview

 

As Flex developers we strive to create user experiences that are engaging and efficient.  The mandate of this mantra requires us to take startup times into account.  When we build our applications, the last thing that we need is for our users to get bored and frustrated before they even start using our applications.

 

part2_preloader.png  

We’re all familiar with the DownloadProgressBar that shows up during preload.  Let’s talk about how to make it go away faster and get users working with our applications in the shortest amount of time possible. 

 

When thinking about application startup optimization, there are a couple things to strive for:

 

  1. Minimizing download time
  2. Deferring instantiation

 

That being said, let’s take a look at the techniques and things to watch out for.

 

Minimizing Download Time

 

Download file sizes and Internet connection speeds can really affect the time it takes for a Flex application to start up.  Unfortunately, those are two factors that we have hardly any control over.  The good news is we have a couple of things that kind of help us in this realm, although they have some drawbacks. 

 

First, there’s caching mechanisms in the modern web browser.  In an ideal end user situation, their browser cache is turned on, so your files can be cached locally on their machine which saves time up front.  The bad news is you really cannot rely on the fact that an end user’s browser will be pulling your files from the cache most of the time.

 

Second, the Flash Player was built to stream frames.  In other words, the Flash Player can start your Flex application while it’s still downloading the application SWF.  The bad news, is until enough of your application has loaded to show frame two, the only thing the end user will see is the Preloader screen.  The reason being, in a standard Flex application there is only two frames.  Frame one is where the SystemManager and the preload process lives, it is the frame that is running when you see the “Loading” display.  The second frame is where your application lives.  This is why minimizing what needs to occur before the preload process completes is crucial.

 

So what is a developer to do to move on to frame two?

 

Beware the Embed

 

The Flex framework makes available to you a way to compile assets such as images, mp3 files and fonts directly into your application SWF.  Although this comes in handy with making sure that the end user will have a copy of your assets this is a very good way of causing your application to remain in “Loading”.

 

For example, take this application that contains an embedded mp3 file that’s just over 9MB.

http://labs.realeyes.com/labs/examples/InsideRIA/Part2/InsideRIA_EmbeddedMp3/InsideRIA_EmbeddedMp3.html

 

If you notice, the application remains in the “Loading” state for a very long time.  This is due to the fact that the application cannot move on to frame two until the 9MB or so of extra SWF has been downloaded.  In the above case, keeping the file externalized and loading it in at runtime would have been a better option to decrease startup time. 

 

Although it may be highly unlikely that you’ll want to embed a 9MB file into your Flex app, imagine an app that has several embedded SVG images, or smaller mp3 files used as sound effects.  Here’s another example, embedded fonts, which is very common.  Let’s talk about fonts.

 

Use Less Character

 

When you embed a font in Flex, you are given the whole range of characters supported by that font.  Although that might be what you’re trying to accomplish with your application, are you sure you need all the characters?  For instance, in an English-only applications are you sure you really need to spend time loading data for Chinese characters?

 

Here’s an example of an app that embeds two different font files with no character restrictions:

http://labs.realeyes.com/labs/examples/InsideRIA/Part2/InsideRIA_FontEmbed_NOT_Limited/InsideRIA_FontEmbed_NOT_Limited.html

 

Now, here’s an example of the same application with a limited character set.  In this case, the font is only being used in some labels that just display numerals, so the character set was limited to use just numbers and the period:

http://labs.realeyes.com/labs/examples/InsideRIA/Part2/InsideRIA_FontEmbed_Limited/InsideRIA_FontEmbed_Limited.html 

 

The thing to note here is if your browser cache is turned on, the difference between the two is negligible, however, if you delete the cached content between requests, you’ll see some serious startup time differences since the SWFs differ about 200KB in size.  In my tests I was averaging about 500ms of savings by using the above technique.

 

Now that we know to limit the sizes of the files we’re serving up, how can we further decrease download requirements?

 

Caching the Framework

 

As of Flex 3 you can now cache Adobe signed framework RSLs into a Flash Player cache.  The beauty of this is twofold.  First, signed framework RSLs cached in the Flash Player cache are shared among all Flex applications that are configured to use them.  In other words, if someone else’s app had already pulled down the 500KB or so of signed framework RSL, and the RSL is still in the Flash Player cache, your application can use that cached RSL.  Second, if someone clears their browser cache, it does not affect the Flash Player cache.

 

There are some caveats to Flash Player framework caching:

 

  • The Flash Player must be version 9.0.115 or higher.

 

  • Framework caching depends on a signed RSL.  In general RSLs increase application startup time since the whole library in an RSL is loaded no matter what.  In other words, even if you’re not using DataGrid and Tree, those classes are getting loaded.

 

  • If you are comfortable with relying on browser caching, then that’s usually going to be a faster startup time due to the nature of how RSL libraries are loaded as noted above.

 

So, here’s an application that uses no Framework caching:

http://labs.realeyes.com/labs/examples/InsideRIA/Part2/InsideRIA_NOT_FrameworkCaching/InsideRIA_NOT_FrameworkCaching.html

 

Here’s the same application using Framework caching:

http://labs.realeyes.com/labs/examples/InsideRIA/Part2/InsideRIA_FrameworkCaching/InsideRIA_FrameworkCaching.html

 

Overall, you benefit from Framework caching if the end user has browser caching turned off and/or their Internet connection speeds are slow.  For instance, I had caching in the browser turned off and after the initial download of the signed Framework RSL I was consistently saving a good 400ms or so.

 

 

Use Modules

 

Another way to minimize that up front load time is to break your Flex application into Modules.  A benefit to using Modules is that you have control over when a Module is loaded into your application and also unloaded.  In addition, you can optimize a module to work with your application, further decreasing the amount of data that needs to be downloaded by decreasing the size of the actual Modules SWF files.

 

Here’s the same application from before, but now we’re using Modules and no Framework Caching:

http://labs.realeyes.com/labs/examples/InsideRIA/Part2/InsideRIA_Modules_NON_OPTIMIZED/InsideRIA_Modules_NON_OPTIMIZED.html

 

Now here’s that same application using Modules, but in this case the Modules have been optimized for this specific application:

http://labs.realeyes.com/labs/examples/InsideRIA/Part2/InsideRIA_Modules_OPTIMIZED/InsideRIA_Modules_OPTIMIZED.html

 

If we keep caching turned off, the startup time gain I was getting by using Modules was about 500ms.  Also, even though the optimized Step1.swf module is about 125KB smaller than the non-optimized one, there really didn’t seem to be any difference between the two when testing with my high-speed Internet connection.

 

Last point to make about Modules is the reason they were faster was because I could load them in just in time.  In other words, the only Module loaded at startup was the Step1.swf Module.  So in this case of Modules, the end-user saved on startup time, but will end up paying for it when they move from one Module to the next since each new Module will need to be loaded in a JIT manner.  In the case of my app, this penalty is when the user moves through each of the steps 1-5 for the first time.

 

So now that we’ve talked about how to improve our application startup time by decreasing the download requirements, let’s move on to how to improve startup time via our application logic.

 

 

Deferring Instantiation

 

The number one thing you can do to help minimize the amount of time from when data is downloaded to when the user can actually use the application is by deferring instantiation.  The concept behind this technique is not creating objects in memory until they’re actually needed by the application. 

 

Although deferred instantiation techniques will cause little - and oftentimes unnoticeable - delays throughout the use of the application, this is often considered more acceptable behavior than having a long application startup delay.  The other benefit to deferred instantiation is optimized memory utilization.

 

When thinking about deferred instantiation, the number one thing to keep in mind is navigator containers such as ViewStack and TabNavigator.  Sometimes developers are tempted to set their creationPolicy attribute to “all” so that they can access children without having a bunch of runtime exceptions caused by null values due to non-existent child components.  The problem with this practice - other than increased memory utilization - is all the child components of the child containers in the navigator are created upfront, before the Preloader display is removed and before the application moves to frame two.

 

Here is an example of the app with creationPolicy=”all”:

http://labs.realeyes.com/labs/examples/InsideRIA/Part2/InsideRIA_CreationPolicy_ALL/InsideRIA_CreationPolicy_ALL.html

 

The good news is that the creationPolicy in your navigation containers is not set to “all” by default.  However, one thing you’ll notice, especially if the navigator children have many children or much associated data is that now when you go from one of the navigator child views to another, is that on first viewing you may see a slight delay as the children of that view are instantiated. 

 

Here is an example of the app we’ve been working with creationPolicy=”auto”, the default:

http://labs.realeyes.com/labs/examples/InsideRIA/Part2/InsideRIA_CreationPolicy_DEFERRED/InsideRIA_CreationPolicy_DEFERRED.html

 

That being said, there’s a way to have your cake and eat it too: ordered creation.  Basically, ordered creation in a navigation container is a two pass beast and tricks the application into turning off the Preloader and moving on to frame two.  During the first pass, the navigator’s immediate child views are created. It is at this point that the application thinks it can display and ends up moving to frame two.  Then on the second pass the navigator’s child view’s children are created. 

 

In this scenario, if we were to use bullet time, you’d see the application initially with instantiated but empty containers, and then you’d see their children pop into view as the Flash Player works its way through the instantiation queue.

 

Here is an example of the app we’ve been working with creationPolicy=”queued”:

http://labs.realeyes.com/labs/examples/InsideRIA/Part2/InsideRIA_CreationPolicy_ORDERER/InsideRIA_CreationPolicy_ORDERER.html

 

All in all, ordered creation is perceived as the fastest option of the three navigator children instantiation choices.  Surprisingly, it’s even slightly faster than deferred creation which I guess makes sense since the first navigator child view’s children need to be created with deferred instantiation before moving to frame two whereas in ordered creation that is not the case. 

 

In my tests, with the browser’s cache turned off, startup time in non-deferred creation was taking around 1100ms, deferred creation around 500ms, and ordered creation around 270ms.

 

One last note on deferred instantiation in navigation containers: if you’re concerned with memory consumption, deferred instantiation A.K.A creationPolicy=”auto” - the default setting - is still the way to go in your navigation containers.

 

 

EXPERIMENTAL: Take Advantage of the Stream

 

Recently I discovered a blog post by a gentleman named Dirk Eismann that created a cool little Flex Builder plugin that I use every day.  Flex Builder TODO/FIXME plugin. (http://www.richinternet.de/blog/index.cfm?entry=911D4B57-0F0D-5A73-AF6F4D4D04099757) 

 

Anyway, his post mentioned taking advantage of the streaming nature of the Flash Player to minimize startup time in your Flex applications without having to use Modules or framework caching. (http://www.richinternet.de/blog/index.cfm?entry=FF295F89-DAD8-CCDC-960413842BC0D478)

 

The key thing to note about this technique is that it deviates from the standard two frame Flex application movie.  Although I can’t take credit for his technique, I decided to expand his code snippets and details into a working example for this blog post which I got "mostly" done.

 

Here is the application I’ve been working with in a seven frame Flex application!

http://labs.realeyes.com/labs/examples/InsideRIA/Part2/InsideRIA_MoreThanTwoFrames/InsideRIA_MoreThanTwoFrames.html

 

The main thing to notice when you run the application is that you can interact with the first form that’s in frame three while all the other forms in the subsequent frames are loading in.  I slowed frames four through seven down by embedding an mp3 into frame four so that you can see this.

 

Like I said before, I didn’t get time to finish it and completely debug the code, and I’m not sure I will since to me it’s non-standard and just a POC, but here’s a couple of thoughts for those of you that want to take Dirk and my work further, which of course I hope you do. J

 

  • I noticed some issues with linking in the code on the alternate frames.  For instance <mx:ComboBox/> was initially throwing an error when you expanded it about IPopUpManager until I created a dummy ComboBox variable in the main app file (to get the classes compiled in)  The alternate way I figured out to handle this ComboBox issues was to uses the signed Framework RSL.

 

  • I had an issue with the data bindings on Step2.mxml.  The problem is an error being thrown on a [mixin] class that was created during the mxmlc compiler's conversion of the MXML files to AS.  I played around with it for a little while and ran out of time before figuring it out. Maybe manual bindings set up in ActionScript would work on these components in frames three and above?

 

 

  • When I had the default Flex Builder compiler setting for locale “-locale en_US” the application was throwing an exception when it tried to load in the controls resource bundle.  I worked around it by setting the compiler argument to “-locale”.  I’m sure this could be fixed…but once again I ran out of time.

 

Based on the above, the multi-frame Flex application, although perceived fast at startup, doesn’t really seem viable for robust Flex coding, at least without a lot of work.  I do, however, see some potential on using this technique to embed resources such as fonts, sound effects, and images that may not be needed right at application startup.  Either way, no matter the fact of its half-implemented state, it’s pretty cool to see a seven frame Flex application. J

 

 

In Closing

 

That being said, it’s time to wrap this up.  Above you were given a rundown on some of the most prevalent ways to decrease your startup times.  The methods I see as most viable is using discretion with embedded data, and using deferred instantiation in your navigators.

 

Below you will find some additional reference links, some notes on the test apps at the links above, and also a taste of what’s coming up next month.

 

 

Additional Reference Links

 

 

* I have a Livedoc comment regarding this one.  Basically, from looking at the Framework source I think applicationComplete is a better place to assess startup times than creationComplete=”callLater(_someMethod)”.  The comment was approved by Adobe, I just don’t see it live yet.

 

About the Test Apps

 

The Flex apps that are linked via this post are view source enabled.  In addition, there are two ways to run these tests on your own:

 

  1. By default, these apps are enabled to work with the REDbug Console.  They do not require the Debug Player for this.  To use them with REDbug, download and install the REDbug, and have it open while the apps are running.  Here is a link to REDbug: http://www.redbugtool.com

 

  1. If you don’t want to use REDbug, you can right-click to view source, download the source zip and import into Flex Builder.  From there you can run in debug mode using the provided trace() statements or roll your own output method.

 

Something to keep in mind during testing is that much of the results can vary depending on network speeds and caching.  Although you can run the tests locally in Flex Builder and see very slight differences, the true test would be to upload it to a web server, preferably not on your local network and test it that way.

 

In addition, it would be best to turn off caching in your web browsers to get a really good feel for average startup times.  I suggest turning off your browser cache and running each test at least three times and averaging the results.

 

Last but not least, the example applications mentioned in this post should not be construed as a full example of best practices.  They are sparsely commented examples slapped together to test some concepts.

 

 

Where We Go from Here

 

In the next installment of this series, we're going to talk about writing efficient code.  During the installment we'll drill down into ActionScript code and discuss some of the things to keep in mind while you’re building your Flex applications.

 

In the meantime, if you have any ideas on what you'd like to see in this series, feel free to post a comment, I'm always open to feedback and ideas.

Read more from Jun Heider. Jun Heider's Atom feed coderjun on Twitter

Comments

23 Comments

Chris Brind said:

Very useful article, thanks.

Here at Arum Systems we've taken the use of Flex modules to another level by developing a platform that reaps the benefit of OSGi (for the server) and Flex (for the client). It is called Solstice and you develop your applications as bundles that contain Java and/or Flex code (unoptimized mx:Modules). As a result you get loosely coupled, highly cohesive and extremely reusable modular applications based on Flex.

It's completely free and totally open source. Feel free to have a look at our alpha release here:
http://www.arum.co.uk/solstice.php

Regards,
Chris

Roman said:

Cool article. But how about having a "print" feature on the site. I could not find any...

Jun Heider said:

@Chris - Thanks for the kind words and very useful tip on your module platform, definitely worth checking out.

@Roman - Thanks! I'll let the powers that be know that a "print" feature would be useful.

Anonymous said:

Great Indian Developer Awards 2008

Vote for your favorite trailblazing individuals & products in the IT Developer ecosystem and win exciting prizes!

Prizes include: Apple Mac Air Book, 26" PLASMA TV, NOKIA95 8 GB, APPLE iPOD 80Gb, ZEST HOLIDAYS, GIDS GOODIES.

The Great Indian Developer Awards is a first-of-its-kind initiative that honors individual & organisational excellence in the IT Developer ecosystem. Just click and cast your vote. With over 15 categories & a distinguished independent jury, who knows... it could be your colleague, company or product that will emerge triumphant. And you get to go home with cool goodies as well! Hurry!

Click here to vote for the Great Indian Developer Awards: http://www.developersummit.com/awards.html#vote

marc said:

great article. My vote for a "print" feature also!

isa said:

Helpful Article!
Yes, a print-feature woud be very nice!

Chris Brind said:

Hi again,

wrt, streaming technique...

When I closed the tab in FireFox that I was running your application in and got an error message similar to "Loading never completed", but of course I am using the debug version of the Flash Player so normally you wouldn't see this. =)

Cheers,
Chris

Jun Heider said:

@Marc @Isa - thanks for the kind words. also regarding the print feature I spoke with the editor and he has passed the feature request on to the webmaster, we'll see. :)

@Chris - interesting, that is definitely good to know and keep in mind for anyone that wants to evolve the technique. thanks for checking out the app and for the the feedback!

Stoyan said:

The urls are not opening. :( Can you repost them somewhere else?

Jun Heider said:

Hello Stoyan,

My company had undergone a hosting provider migration and as a result all the labs.realeyes.com url needed to be changed.

I made the url changes to this blog entry and the links should all be working now.

Jun Heider said:

李哲,

You're welcome!

Jimmy said:

Great Article, Some really informative points discussed about flex Framework and concept of downloading and minimizing the downloading speed , this is what we read in VCP-310 virtual exam to get the things done in time.

Ilan Avigdor said:

Your description of what happens in Flex's two frames implies that the user will see the loading progress bar only at the first frame.
As far as I know, the SystemManager (which lives in both frames, not only in the first) advances to frame 2 upon completion of download,
,creates and initialize the application.
INIT_COMPLETE is dispatched when the application has completed initialization. Only then will the progress bar disappear.
Therefore, our goal is not "move on to frame two", but minimize download and application initialization time.
Other than that, Great post !

Jun Heider said:

IIan,

You're right about the SystemManager. Also, regarding "Therefore, our goal is not "move on to frame two", but minimize download and application initialization time." Great point.

Thanks for the read!

B.Rotrou said:

hi
starting, sorry for my bad english.. ;-)

thank for the quality ou your article.

i would like to knows how you reduce the size of your embed font file, it is possible with true type ?

witch way for use only Character we use for on language .

I dont want take you too much time but maybe can you tell me a place where i can find informations on this subject.

thank a lot


Jun Heider said:

@B.Rotrou

You can take a look at the following LiveDoc to figure out how to limit the character ranges in your embedded fonts:
http://livedocs.adobe.com/flex/3/html/fonts_07.html#131075

Hope that helps!

B.Rotrou said:

thank , for your help , i had not seen this part of doc .
thank

Jun Heider said:

@B.Rotrou

You're very welcome.

jessica said:

Now that you've had a chance to get your feet wet with Adam and Scott's outstanding InsideRIA series on Learning Flex From Scratch (LFFS) it's time to start really thinking about optimizing your apps 000-076 exam. Many new developer are just happy to build an application that works without thinking of the consequences of poor architecture, inefficient code, and over-zealous eye candy. Although you may be fine for a while, eventually a lack of concern for performance is going to stop you in your tracks. Thanks to Murphy's law, this inevitability will occur most often on very large or important projects, and oftentimes after they're two days away from launch.

ᅠ That being said, the idea behind this series is to arm you with the information you'll need to change the course of your development future and prevent any future crises moments from happening JN0-521 exam.

ᅠ The other idea behind this series is to post-process the resources that are out there, if necessary, revamp them to be current to today's Flex 3 platform, re-affirm them with additional examples and insights, or extend them in an OOP-like fashion to derive some more comprehensive materials.

muffin9129 said:

Yeah you cannot copy and paste it either because you lose so much of the formatting, great articles, but need to print it.

Pat.R said:

This is way over my head. Is there anything a little more basic I could check out?

Jay Paroline said:

I am finding the articles on this site useful and informative, however every example app that you are linking to gives a 404. Are these available anywhere?

Jun Heider said:

@muffin9129

Printing the articles in a pretty format is a good suggestion, thanks!

@Pat

You might want to take a look at the Flex documentation. It usually presents the material in a way that someone getting started would catch on easily.

@jay

Thanks for pointing this out. Apparently, something happened at the hosting provider. I'll take a look into it.

Leave a comment


Tag Cloud

Question of the Week: Dream App

If you had an unlimited budget and unlimited resources what application would you build and why would you build it?

Answer

Latest Features

Recommended for You

@InsideRIA on Twitter

Archives

  • Or, visit our complete archive.  

About This Site

Welcome to the premiere community site for all things RIA sponsored by O'Reilly Media and Adobe Systems Incorporated.