Many wise advisors recommend that we use descriptive variable names in our code like "var index:int" instead of "var i:int".  However, if you look at the set of strings used for property names in most code, a significant amount is given to variable names that the user never sees.  The Google Closure Compiler (GCC) looks for variables that aren't used as strings elsewhere and renames the variables in the output code to shorter names like "a" and "aa".  This can make a difference in the total download of the application.

This also often breaks code.  Your server probably doesn't know the application code that was expecting a 'firstName' property is now going to try to access it as 'a'.  So really, you want to tell GCC that certain variables should not be renamed.

In FlexJS, public variables do not get renamed.  This makes GCC a bit less efficient, because many public variables probably could get renamed, and maybe future versions of the compiler will be smarter about that, but for now, making sure your code is accessing instances with public properties instead of plain objects is the key to preventing bugs from GCC renaming variables.

Making sure your code is accessing instances instead of plain objects can often be tricky.  For example, you might create a new instance of a class and assign it to an Array.  But as soon as you retrieve it from the Array it may no longer be seen as an instance.  It may be seen as a plain object.  For example assuming a class Person that looks like this:

public class Person() {
public var firstName:String;
}

Then code you write like this should be ok.

var foo:Person = new Person();
foo.firstName = "Alex"; // this will not get renamed. 

But the following will not work:

var bar:Array = [];
bar.push(foo);
bar[0].firstName = "Fred";
 

This is because bar[0] is not known to the compiler as a Person, it is a plain object, so GCC will generate code like bar[0].a

So, you have to be more careful in ActionScript to use class type information in more places.  So in this case the following will work:

var baz:Person = bar[0] as Person;
baz.firstName = "Fred"; 

But these will not:

Person(bar[0]).firstName = "Fred";
(bar[0] as Person).firstName = "Fred"; 

One might think that use of coercion might work as well, but it won't because the compiler converts coercions to function calls that return plain object, so assigning to temporary variables is currently the recommended practice.

 

  • No labels