wvxvw
04-12-2009, 11:03 PM
Have you ever though about Flex compiler can be a bit smarter?..
I had almost never seen such ideas in the wish-list, or any boards. But, digging deeper into framework stuff and, especially into generated code I keep catching myself at thinking that the code is way to far from being optimized... Well, you may know how smart C compilers can be, and, actually, they can compile very different sources into the same bytecode making optimization whenever possible, independent of your coding techniques and style it may give you pretty optimized example in the end...
Do you remember, there was Flasm utility once that let you optimize the AS bytecode after it was compiled. Well, the code generated if you use MXML and, especially if you use it with mx framework is highly nonproductive... let alone it imports so much needless stuff, it also makes it work very slow...
Imagine this simple example:
<mx:Button id="myButton" click="clickHandler()"/>
You'd guess it'd be translated into AS code like this:
myButton.addEventListener(Event.CLICK, clickHandler);
private function clickHandler(event:Event = null):void { ... }
Guess you ware ware wrong... it'd be:
myButton.addEventListener(Event.CLICK, _my_package_myClass_myButton_clickHandler);
public function _my_package_myClass_myButton_clickHandler(event:Ev ent):void
{
clickHandler();
}
private function clickHandler():void { ... }
So, we have here:
- one useless callback
- one sticking outside public method (what for?)
- if you don't know how compiler generates the names for the listeners you'd never be able to removeEventListener. But, even if you do, that's the same way a lot of string parsing involving describeType(), getDefinitionByName() etc...
Well, I can imagine this was an easiest way to generate the handler, but, sure this way is far from being perfect!
And you really don't want to look into how Flex generates binding... that's not just ugly, it's totally wrong... if you'll ever happen to have more then one instance of the same MXML component you'd run into this problem some time ever so often...
Now, if you ever had run the profiler, you could see how many objects and of what type are created during your application being executed... Now think about how many classes and, potentially, objects could be created by all the must-import Flex classes - let me reassure you that if all the objects that may be created by using the framework where created only once it would probably break the profiler, just because there are to many of them.
But, instead of optimizing the compiler, making it smarter, the framework introduces bunches of dirty workarounds!.. Like, for instance, generating UIDs for all framework objects (which is quite computation intensive process), every class that depends on other classes doublechecks, or even triplechecks if the input was correct... even though there are compile- / run-time errors!
Every even the most simple thing has:
- all the framework classes in it's dependencies
- is 10 times bigger / has way much more functions than an average developer would ever need.
- it's functionality is always covered by 2-3 similar classes...
Speaking of data management:
- Why, oh, why should ArrayCollection implement IList? There's no reason on Earth it should.
- If it wouldn't implement it, you could pool it from the framework and use it alone. But, since it does, at some point it gets to refer Application.application in a hardcoded way. So, not a chance you can pool it out of the framework! (BTW. Application.application is technically synonymous to _root in AS2, but much worse, because _root was just an alias and Application.application is the real non-player class that will force you into importing all the framework, including resource bundles, default styles etc.).
Now, because the framework is heavy, and you cannot use it in any other way, but in one piece, there's another workaround - shared RSLs, which, again, are buggy to the point you would finally decline this option. Besides, they are available only for few SDK builds, which are not always the builds you like to use... Even though, after you took your chances with signed RSLs and have your application sliced into numerous modules, you discover that modules are also buggy up to the point you don't want to even try to use them... But, even, imagine you hacked around the ModuleLoader (basically have it rewritten and recompiled instead of the one you have in the SDK), the file isn't going to get less than 50K! You can leak your elbows, but you cannot remove useless stuff from your framework SWF...
Sorry, I may be delirious after a few days of banging my head against the wall trying to get data that is compiled into the SWF with -services argument... And this is again, because it is done in the SDK in the pretty ugly way:
the compiler just adds this line:
ServerConfig.xml =
<services>
....
</services>
Into the Application-generated.as file... but that's just stupid there's no way to get it if your project isn't using framework... :mad:
I had almost never seen such ideas in the wish-list, or any boards. But, digging deeper into framework stuff and, especially into generated code I keep catching myself at thinking that the code is way to far from being optimized... Well, you may know how smart C compilers can be, and, actually, they can compile very different sources into the same bytecode making optimization whenever possible, independent of your coding techniques and style it may give you pretty optimized example in the end...
Do you remember, there was Flasm utility once that let you optimize the AS bytecode after it was compiled. Well, the code generated if you use MXML and, especially if you use it with mx framework is highly nonproductive... let alone it imports so much needless stuff, it also makes it work very slow...
Imagine this simple example:
<mx:Button id="myButton" click="clickHandler()"/>
You'd guess it'd be translated into AS code like this:
myButton.addEventListener(Event.CLICK, clickHandler);
private function clickHandler(event:Event = null):void { ... }
Guess you ware ware wrong... it'd be:
myButton.addEventListener(Event.CLICK, _my_package_myClass_myButton_clickHandler);
public function _my_package_myClass_myButton_clickHandler(event:Ev ent):void
{
clickHandler();
}
private function clickHandler():void { ... }
So, we have here:
- one useless callback
- one sticking outside public method (what for?)
- if you don't know how compiler generates the names for the listeners you'd never be able to removeEventListener. But, even if you do, that's the same way a lot of string parsing involving describeType(), getDefinitionByName() etc...
Well, I can imagine this was an easiest way to generate the handler, but, sure this way is far from being perfect!
And you really don't want to look into how Flex generates binding... that's not just ugly, it's totally wrong... if you'll ever happen to have more then one instance of the same MXML component you'd run into this problem some time ever so often...
Now, if you ever had run the profiler, you could see how many objects and of what type are created during your application being executed... Now think about how many classes and, potentially, objects could be created by all the must-import Flex classes - let me reassure you that if all the objects that may be created by using the framework where created only once it would probably break the profiler, just because there are to many of them.
But, instead of optimizing the compiler, making it smarter, the framework introduces bunches of dirty workarounds!.. Like, for instance, generating UIDs for all framework objects (which is quite computation intensive process), every class that depends on other classes doublechecks, or even triplechecks if the input was correct... even though there are compile- / run-time errors!
Every even the most simple thing has:
- all the framework classes in it's dependencies
- is 10 times bigger / has way much more functions than an average developer would ever need.
- it's functionality is always covered by 2-3 similar classes...
Speaking of data management:
- Why, oh, why should ArrayCollection implement IList? There's no reason on Earth it should.
- If it wouldn't implement it, you could pool it from the framework and use it alone. But, since it does, at some point it gets to refer Application.application in a hardcoded way. So, not a chance you can pool it out of the framework! (BTW. Application.application is technically synonymous to _root in AS2, but much worse, because _root was just an alias and Application.application is the real non-player class that will force you into importing all the framework, including resource bundles, default styles etc.).
Now, because the framework is heavy, and you cannot use it in any other way, but in one piece, there's another workaround - shared RSLs, which, again, are buggy to the point you would finally decline this option. Besides, they are available only for few SDK builds, which are not always the builds you like to use... Even though, after you took your chances with signed RSLs and have your application sliced into numerous modules, you discover that modules are also buggy up to the point you don't want to even try to use them... But, even, imagine you hacked around the ModuleLoader (basically have it rewritten and recompiled instead of the one you have in the SDK), the file isn't going to get less than 50K! You can leak your elbows, but you cannot remove useless stuff from your framework SWF...
Sorry, I may be delirious after a few days of banging my head against the wall trying to get data that is compiled into the SWF with -services argument... And this is again, because it is done in the SDK in the pretty ugly way:
the compiler just adds this line:
ServerConfig.xml =
<services>
....
</services>
Into the Application-generated.as file... but that's just stupid there's no way to get it if your project isn't using framework... :mad: