The great AS3/AS2 debate: Is it slower to work with AS3 than AS2? My take: A bit

Mike Chambers, Principal Product Manager for developer relations from Adobe, has been pinging the Flash community about whether AS2 based development is faster than AS3 for Flash projects. Having spent a long time in both languages, I thought I would post my 2 cents on this blog. So my answer is: Yes. Of course I’ll qualify my statement by saying that 1) There are a lot of capabilities in Flash 9+ that are amazing but I want to disconnect the language (pure syntax) from what it enables and 2) This post assumes you are as comfortable with AS3 as AS2. I am not factoring in the learning curve for a new language, which happens anytime there is a drastic change.

AS3 can use some help. Let me list out some reasons why I say that:

  1. Loading XML is a complete pain
  2. Calling an external URL is AS2 was simple (although having to use delegate because of the lack of proper closures was retarded). The code was something like this:
    [AS]
    var xml:XML = new XML()
    xml.ignoreWhite = true;
    xml.onLoad = function(success){
    if(success){}
    else{}
    }
    xml.load(‘doc.xml?foo=bar’)
    [/AS]

    Very readable, plus all errors were available in one check. Lets compare that to AS3:

    [AS]
    XML.ignoreWhite = true;
    var urlLoader:URLLoader = new URLLoader()
    var urlRequest = new URLRequest(‘doc.xml’)
    var urlVariables = new URLVariables()
    urlVariables.foo = bar
    urlRequest.data = urlVariables
    loader.addEventListener(IOErrorEvent.IOError, onError)
    loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onError);
    loader.addEventListener(Event.COMPLETE, onComplete)
    urlLoader.load(urlRequest)

    [/AS]

    How verbose is that? I am still trying to figure out why every request needs a URLRequest object, seems unnecessary. just calling urlLoader.load(“data.xml”) could automatically create a URLRequest object, if you ever want to examine a request post it being called. Another huge problem is most developers I know dont actually add the error event listeners, just cause adding it is so tiresome. So when an error occurs later, they are usually clueless to what happened (was it a code bug or did some http call out just did not work?).

    The URLRequest param for navigateToURL seems another one of those requirements that seem unnecessary.

  3. Whoops, forgot my addChild
  4. I think this is where I have lost countless hours, I would create a sprite, and set its properties, but forget to add it to the stage…and then spend too much time to figure out what did I do wrong. The only way to create a new UI element in AS2 was by referencing an already added MovieClip (remember my_mc.createEmptyMovieClip() ?). I would love to have a createAndAdd function in DisplayObjects that becomes the default way of creating new Sprites.

  5. Dynamic drawing: The graphics object
  6. Drawing in AS2 was simpler: MovieClip.lineTo(….). In AS3 it has to be on the graphics context of the DisplayObject (mySprite.graphics.lineTo() ), but why? There isnt any other context to draw on, and the graphics context isnt swappable, so why do I have to type that in?

  7. No numeric depths
  8. In AS2, you could set explicit depth numbers to elements and reorder elements under those depths. So for example, if you were writing a button control, you could set the label field up on depth 1000 and keep swapping out the children under it. In AS2, you have to track where in the display tree your element is.

  9. useHandCursor vs ButtonMode + useHandCursor
  10. I dont know what buttonMode does besides actually allow me to useHandCursor property, which I have to set anyway

  11. No onReleaseOutside
  12. This one also is weird. The way we now have to do an onReleaseOutside is via listening to a stage click event. But wait, you may not be on stage yet, so you need to check : if(stage), and also write an event listener to the addedToStage event. Verbose.

  13. addEventListener vs. onRelease
  14. onRelease (and similar “on…” functions) is not a bad default hook to have. Considering how often we write these functions, having a quick shortcut to the action was nice. Not that I am saying the event model is bad, but I end up writing a lot of addEventListeners and removeEventListener throughout the code.

I think overall, when I look at an AS3 file, it just seems longer than AS2 code used to. I think everything needs to be very explicitly set in AS3 with no smart defaults. Maybe that’ll change in AS4 now that we no longer care for the ECMA spec ;). There are a lot of improvements in AS3 as well though, like actually having private and protected namespaces, but I am only listing out my pet peeves here hoping Mike takes note :). Flash is an amazing platform, and I love what it enables me to do.

Isn’t quality code a feature ?

I have had a few conversations with some fellow developers here and there (most often with Mat) around code quality, and sometimes I get really frustrated to see what passes for “Good enough for now” code. In user interface development, its very easy to confuse all work with all visually displayable features. But when you are going to live with the code for a while or this code is going to be the foundation of later features, how can you not track code quality?

And of course there are extremes to that argument. I have worked with enough wannabe-architects who want the code to be pristine and who would much rather write their perfect piece of software no matter what the cost (in terms of time, features dropped or developer-pay) is. They should be tarred and feathered cause they weaken the valid calls for code quality.

But there has to be a middle ground here. The problem is well-written code is hard to quantify. Features are blessed with visibility but architecture isn’t. I had a conversation with a friend yesterday on how I prefer being a developer to a designer since design is so subjective, and what I might think is wonderful design may be pooh-poohed by someone else (worse, my theoretical manager), but code either works or it doesn’t and thats instant feedback.

Software architecture or “well-written code” seems to suffer from the same problem of subjectivity as design to some extent. And if you are fortunate enough to actually have a conversation around code quality (and I dont mean in the theoretical sense but you actually sit down and review what you have written), its lack of visible benefits to the product makes it one of the first things to be dropped when trying to make deadlines.

How do you quantify code quality then? As a developer I can tell you it has real returns. In my (Flash) world it sometimes translates to faster load times, less taxing of the CPU, smaller number of classes to be maintained, but its really hard to measure. How do you say the swf weighing 300k is worth the extra couple of weeks than a swf weighing 600k that was never written but would have if checks on code quality weren’t there. How do you measure against something that never existed ! Worse, how do you track that when there is no feature that maps to lighter swfs ?

And then there are the the really invisibles: dead code paths within code, extra classes that you dont use or are so badly written that they are such pain to work with that other developer on the project just writes new classes with the same functionality? How do you check such things? How do you justify investment in tools that enable high quality code ?

Heck, if you had to justify version control, how would you? Thank God some things like that dont have to be justified anymore but when will that stature be given to tools like Review-Board. Is code quality just a developer itch ?

Do you track code quality ? How ? Do you use any particular tools ? Do you have coding standards ? Please share your thoughts here, cause I am really curious.

Does good code-base just accidentally happen to get written or is there a process to get to it ?

A sneak peek at OpenPyro: A lightweight alternative to Flex

For the last few months, I have worked quite a bit with Flex and at times, the complexity of the framework really makes it hard to work with. I have mentioned my problems with Flex in an earlier post but the gist of it was:

  • A lot of our projects are widgets rather than apps that are as big as the webpage itself. The smaller the apps get in dimensions, the more unacceptable the load time becomes, so we could not create apps that compiled to swfs greater than 250k (even with framework caching).
  • Flex apps are memory intensive on their own and I really need that memory for other things like rendering high def video (which a lot of our apps do).
  • I want to build apps that are more expressive that what Flex lets me do.

Given these requirements, I have started working on an open source framework modeled after the Flex framework but with the primary goal of being really light and easy to extend. The project is actually being developed within the Flash team at Comcast Interactive Media to allow us to develop apps faster and give all the developers here a common standard to develop against. It started out as an R&D project but is now an official CIM project, so will definitely evolve in the next few months.

OpenPyro is not really complete but its at a good point where I can show it off a little bit and get some feedback. Here is what the framework does so far:

  • A bunch of pre-built components like Buttons, Sliders, Scrollbars, etc (1.0 release should have most of the components we are used to)
  • Has an explicit component lifecycle very similar to Flex with the concept of invalidation and differed UI update
  • Layout management including using percent based layouts (so you can set a dimension of a control as a percent of the container its sitting in using percentWidth or percentUnusedWidth). Also there are no layout specific containers (like H or VBox) but rather a container can be assigned any layout.
  • Runtime skinning
  • Separation the look of the controller (based on a skin file) with its behavior (like Flex 4 or OpenFlux) [work in progress]
  • Concept of Painters (not as complex as Degrafa yet but still pretty good and getting better)
  • The components are not tied to the framework. So you can just use a component like a Scrollbar or Slider in your As3 / Fla project.

The best part is even some pretty complex layouts like the image below weigh only around 23k. Imagine doing that with separate V and HBoxes.

There is also a bunch of other classes (a collections framework-esque package as well as a host of utility classes) that I will migrate to OpenPyro once the core components are at a good point. So stay tuned for that.

Of course with all its wins, there are still things in Flex that OpenPyro will not be able to do:

  • Data Binding: Since Flex does this at compile time using code generation, this has not been done.
  • XML based layout: This may happen later (and may or may not be compile time) but this is definitely a phase 2 thing.

I will post more examples in a couple of days to show some actual apps built with OpenPyro, but in the meanwhile take a look at the video below and let me know if you have any comments on the direction the framework is taking. If you want to look through the source code, the project is hosted at the github. OpenPyro will be released under the MIT license. There is also a google group for the project at http://groups.google.com/group/as3-pyro-user-group/.

https://arpitonline.com/blog/examples/openPyro/OpenPyro_intro.swf

Re: Bit-101 on putting the Flash back in Flash

I have this love/hate thing going with Flex off late (if you know me personally, this would be no surprise to you). While I do love the Flex IDE with code completion and language intelligence, the Flex apps that I see on the web are a far cry from the kind of experiences that got me into Flash. So when I heard Keith Peters, aka Bit-101, gave a talk on “Bringing the Flash back into Flash” at Flash Forward ’08, I pinged him over Twitter asking him if he could share what he presented (as I am sure others did as well). So he did and it was a good read, I strongly recommend reading it here.

Having worked a lot with both technologies, I kind of feel let down by both of them just about as much. Unlike Keith, the experience I would like to see isn’t the ostentatious experiences that made 2advanced and such studios famous. While they definitely caught the eye, the crazy zap zoom effects wear thin on the second or third visit. The experience I would like to see Flash/Flex enable is closer to the experiences that Apple seems to enable (disclaimer: I am no Apple fanboy, and find a lot of things they do completely wrong). They are simpler effects but dont make you stop doing what you are doing and wait till the animation ends. I love my IPhone and just compare the experience there to any other Flash experience on a RIA. Both Flash and Flex fail pretty bad on that front. Here is why:

Flex 2/3:

  • Poor user experience by default
  • I dont get it how the core Flex 3 experience is acceptable by Flex developers. Non scrolling lists ? C’mon ! No control over itemRenderers in List controls (can you grow one’s width and height without having it clipped off by its neighbour ? ). Hacks to get any kind of custom Tooltips ? These are few in a long list of gripes I have with the framework

  • Really hard to extend core components
  • Its really amazing how hard it is to extend any Flex component, so much so that entire frameworks have been built just to do that (read about OpenFlux here). Flex 4 promises to ease this but thats still a year away.

  • Tightly coupled framework
  • It really kills me how tightly coupled the Flex framework is. There is no way to use, for example, just the collections framework without pulling in the UI framework. Why cant dataBinding be used in pure AS3 projects ?

  • Transitions/Effects an afterthought
  • Out of the box, Flex has no effects or transitions built in. So you have to explicitly create transitions but I wish out of the box some effects were enabled.

  • File Size
  • The huge swf size of a Flex app makes it unusable for any kind of widgets or smaller dimension swfs, and Flex 4 will not change this (their roadmap states that Flex 4 files will be around the same file size as Flex 3). The size of the swf goes beyond the load time. Heavy core objects mean they are more taxing on your CPU, which explains why complex animations with more than a few UIComponent objects stutter.

Flash

  • Really poor code editor
  • The quality of the code editor is really poor in Flash, enough for me to never use it.

  • Version control nightmare
  • Any code within the timeline is a nightmare for version control so you have no idea when your project is a few months old what the changes were. Same thing with any changes to a graphical element.

  • Write everything from scratch
  • I am not a fan of the Flash components architecture, which offers less capabilities than the Flex component set. So I end up writing components from scratch.

So what I am really looking for is a framework I can use in Flex Builder that is lighter than Flex and is more expressive by default. I have been working on a project that may enable those features that I am hoping to release soon, so do stay tuned.

Quick Poll: Whats your favorite Flex feature ?

Having worked with Flex long enough there are definitely times I get really annoyed when Flex does something I feel is counter intuitive or when I have to go around a pretty complicated process to do something that I feel would be trivial in Flash. But given a limited time frame for a project, I usually default to a Flex project as opposed to a pure AS3 project just since there are so many conveniences in the framework.

I am curious how the rest of the Flex community feels now that Flex has been out there for a while and the “new-and-shiny” effect has worn off. So I would like to ask, the following question: What is your favorite feature of the Flex framework. Below is a poll widget but it may be restrictive to your answer, so feel free to comment or elaborate on what you love/hate about the framework.

Whats your favorite Flex feature ?
( polls)

Thanks all

AS3 weirdness with URLVariables for HTTP POST

Two+ hours wasted today on dealing with this. Apparently when using URLVariables to pass variables to the server using HTTP Post, using the square bracket syntax ( vars[varname] = varvalue ) sets the contentType of the URLRequest to text/html. However setting the same variables using the dot syntax (vars.varname = varvalue) sets it to text/xml. I couldn’t set the contentType to text/xml using the [] notation no matter how I tried, whether using the URLRequest.contentType property or appending a custom “Content-Type”,”text/xml” URLRequestHeader.

Hope this helps someone.

Starting a new blog

One is such a lonely number ;). This weekend I launched a new blog:The ‘Pit Stop at http://arpitmathur.com. Unlike Code Zen (this blog), where I have tried really hard to keep personal commentary to a minimum and make it as developer focused as I could with a lot of source code and tips for web development, the new one is going to be more on my opinions on (among other things) the social web and the evolution of the online experience from a geek’s point of view. More on the why here. In the meanwhile, this blog will remain the outlet for all my developer focussed stuff (I am still a coder at work).

Do let me know what you think and please add The ‘Pit Stop to your feed readers.

Cheers

Code Zen added to RIA.alltop.com

Yup. This blog is now aggregated by Guy Kawasaki‘s latest project: alltop.com. Specifically, http://ria.alltop.com, the channel dedicated to Rich Internet Applications. I share the space with some pretty big guns in the RIA domain, so thats pretty exciting :). For those not in the know, alltop is a site aggregating top shelf content from across the web across different subjects, and present them in an easy to scan layout (very popurls, which I love πŸ˜‰ ). So do check out the different channels on alltop.com and see if you like it.

Dayum, have to up the quality of my posts now. No pressure, no pressure …

Debugging crossdomain issues: Following HTTP 302s

Flash’s crossdomain access policies have always been one of the things developers have always complained against. The specification keeps changing, even with minor updates to the Flash Players (actually I dont really know what counts as a major release in Flash Player land, all releases are point-point-point releases like 9.0.124.0, making them look really minor). I lost more than 2 days on cross domain issues last week before I finally figured it out. So I figured blogging this could help someone else not waste as much time as I did.

If you are reading this post, also check out my previous crossdomain entry as well, which talks about setting up the Flash logging as well as the newly introduced content-type strictness that broke my last app.

In this particular entry I want to talk about how Flash handles HTTP 302 headers while loading images using a Loader, as well as certain tricks to debug crossdomain related issues. While Flash does load images from outside its security sandbox, it does not give you access to the BitmapData of those images which is what I was trying to do.

Whats HTTP 302 ?
HTTP 302 http header tells the browser that the content has been moved temporarily to a different URL. When the browser receives this message it immediately tries the new url. The header is explained in more detail here.

Why is this a problem ?
The problem occurs when you try to load a resource from a url that may redirect to a url outside the security sandbox of the swf. Although Flash automatically calls the new url, it does not use any loaderContext. The LoaderContext object is the optional argument to a URLRequest when making data request calls using a Loader that tells Flash Player to look for a crossdomain.xml file. The first thing that usually causes errors is that the developer forgets to pass this argument. As far as I remember, AS2 used to look for crossdomain files automatically when making cross-domain calls but AS3 does not. But even when you pass this parameter to a Loader’s load function, if the url automatically redirects using 302, the Flash player does not use the LoaderContext in the subsequent call.

The solution:
The way to resolve this (and I only found this after way too long), is to look at the url of LoaderInfo object of the Loader object (Loader.contentLoaderInfo). This data is populated with the new redirected-to URL at the time when the Loader fires the HTTPStatusEvent (and all events following that). Your code needs to check if the final url was different from the original url and if so, load the new URL again, using a LoaderContext that makes the loader look for a crossdomain.xml. The code looks something like this:

[AS]

public function ImageLoadTest(){
l = new Loader()
l.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadComplete)
addChild(l);
load(imageURL);
}
private function onLoadComplete(event:Event):void{
try{
trace( Bitmap(l.content).bitmapData)
}catch(e:Error){
trace(‘Cannot access bitmap of image due to crossdomain issues’);
load(l.contentLoaderInfo.url);
}
}

private function load(url:String):void{
var context:LoaderContext = new LoaderContext(true)
l.load(new URLRequest(url), context);
}

[/AS]

This seems a little idiotic, and makes every load takes twice as long, not to mention consume twice the bandwidth. If anyone knows another way to do this, let me know. However if you do not know the location of the final server up until the time of loading, then this seems to be the only way.

Setting up Flex Builder projects to surface cross domain errors:

The worst part of this bug is that it will never surface when you are developing the code using Flex Builder, since by default, Flex Builder uses the file protocol (file://) to reference the html and swfs, and at this time, all http calls regardless of domains, are allowed. So this bug came up only during the QA phase and seriously jeopardized my project. The way you *should* develop Flex/AS3 projects in Flex Builder is to switch the location of the output folder of your project to the documentRoot of a locally running HTTP server (Macs come with Apache 2 built in, and its an easy install for Windows), and then use the http:// protocol to reference the file. Make sure to change the host file on your machine to reference that page as a subdomain of the project’s final web location. Now all security sandbox errors will come up as you develop your app in the trace console window of Flex Builder

Flex Builder Web Project

Verify crossdomain files with Charles:
I use Charles, an http proxy, to monitor the http behavior of my application. Charles comes with a very nifty feature called local mappings that lets you load local files when the browser makes certain calls. I ended up using this to load crossdomain files sitting on my desktop everytime Flash made certain http requests for them, really a great tool considering the schema has changed a bit in the last few versions of the Flash Player.

Charles Local Files

And of course enabling Flash Player logs is absolutely essential while debugging Flash Player cross domain issues.

LogBook and Application Performance

Its exciting to see LogBook, Comcast Interactive Media’s first open source project get some traction. There is talk of LogBook being included in other open source projects as well as people have started submitting patches and suggestions to the project.

One issue that was submitted a few days back was around the Logging implementation dispatching all logging events out of the application across the LocalConnection. Here is a quote from the issue:

Logging could add significant overhead to an application, due to
log message construction, and sending messages to LogBook.

It is good practice to minimize logging overhead, with code like:

if (Log.isInfo()) {
LOG.info(“version: {0}”, version);
}

The current implementation of class LocalConnectionTarget always
sets the log level to ALL and the log filter to “*”. This means
that all logging methods are executed, which is undesirable.

You can see the details of the issue here.

I just wanted to elaborate a little on why the LocalConnectionTarget class does not use any kind of filtering to reduce the number of LogMessages being constructed.

One of the reason we went with LogBook as an AIR application as opposed to a web application was because as far as I know, the Flash Player process on the web is independent from that in AIR. This means that LogBook could become a very elaborate application on its own but it will not impact the performance of the application using LogBook based logging. Also when we pass objects across LocalConnection, these objects do not accumulate in the application’s memory. Here is a screenshot from a quick experiment where I ran an endless loop that created a custom LogDispatcher object, had it send a log message across the LocalConnection and then get garbage collected. The memory profile of the application can be seen below:

LogBook App Memory Profile

Here is also the live objects screen capture:

LogBook Enabled App Live Objects Screen Grab

As you can see, over 600 objects were constructed but all of them could be garbage collected with no overhead in terms of memory used.

So your take away from this discussion is: using LogBook has virtually no memory overhead in your application. The idea of broadcasting all messages to LogBook is to allow you to filter the data on the client at the moment of debugging or after, rather than configuring it at some pre-launch time.

Now LogBook itself is another story. Another bug submitted by the same developer who reported this also talked about LogBook’s performance when over 1000 messages were collected, and yes, I have verified that at that point, the application becomes pretty sluggish. So for the next version of the LogBook, I am considering leveraging the SQLite database that AIR comes packaged with.

More on LogBook 2.0 soon. We are already on it and it will be good ;). If you would like to participate in defining the functionality in 2.0 or better yet, help us develop it, join the conversation on the LogBook user group here.