Alex, I had also considered the same idea of doing the qualifiedName splitting in the reflection data because I think you would reduce a lot of long string variation in the GCC release build simply by doing 'org.apache.flex.'+'Package.'+'ClassName' etc
Isn't using the reflection member definition names for access also another use that would qualify as 'dynamic' access? I am not sure if GCC can make the connection between the reflection data field names and the original naming of the fields which is why we need @export on instance members and @expose on static members (without those it fails iirc). One option for the future might be to make Reflection support optional. I think we might still want FLEXJS_CLASS_INFO, but perhaps the rest of the the reflection support could be opt-in (or opt-out). This alone could reduce a lot of code for people who don't need that. On Thu, Sep 29, 2016 at 6:17 AM, Alex Harui <aha...@adobe.com> wrote: > > > On 9/28/16, 3:25 AM, "Harbs" <harbs.li...@gmail.com> wrote: > > >I like this idea and would propose taking it one step further: > > > >Currently transpiled javascript has fully qualified class names for > >pretty much everything. This is difficult for closure to minimize > >completely. I’d really like to have some way to “export” class names as > >well as “import” to define some compact name for packages. Based on my > >playing around, this could save at least tens of KB of JS downloads. > > For sure, the amount of download for strings is a significant waste of > bytes in most cases. However, I'm not sure we need to provide renaming > controls for folks building FlexJS apps, at least not for the mainstream. > > AIUI, every public property and method in FlexJS is "exported" to prevent > renaming for a few "just-in-case" reasons. First, a review of renaming: > > FlexJS uses the Google Closure Compiler to optimize/minify the output JS > file. In doing so, GCC tries to renaming variables. For example, every > FlexJS class has a FLEXJS_CLASS_INFO property on it. Google might rename > that property to just "a", so the original JS might look like: > > UIBase.prototype.FLEXJS_CLASS_INFO = {..}; > > But GCC will cause that to look like: > > UIBase.prototype.a = {..}; > > If you replace "FLEXJS_CLASS_INFO" with "a" in every FlexJS class, you can > save quite a bit of download size. But then, what happens if someone > writes code that looks like: > > var foo:Object = someUIBase.FLEXJS_CLASS_INFO; > var bar:Object = someUIBase["FLEXJS_CLASS_INFO"]; > > For the first line, GCC will know to alter the code to look like: > > var foo:Object = someUIBase.a; > > And everything will work fine, but AIUI, GCC does not try to alter strings > so it will not touch the "bar" code and that would fail at runtime since > there is no longer a property called "FLEXJS_CLASS_INFO" on UIBase. > > > But I think that GCC is now smart enough that if you actually have a line > like the "bar" line, that will prevent GCC from renaming > FLEXJS_CLASS_INFO. GCC might make an alias instead. GCC knows that the > output must have the bytes for "FLEXJS_CLASS_INFO" once in order to honor > the string literal, so it will create an alias like aa = > "FLEXJS_CLASS_INFO" and then the code is output as: > > UIBase.prototype[aa] = {..}; > And > var foo:Object = someUIBase[aa]; > var bar:Object = someUIBase[aa]; > > IOW, GCC has a pretty good alias generator, which is why I don't think our > tool chain needs to provide folks with the manual options to rename. We > should just let GCC do its thing. > > > So, AIUI, the reason we export every public thing isn't for the standard > dynamic access case as shown above, but for two others (and related > scenarios): > -Dynamic access using generated strings > -Binding expressions with "dot-paths" > > Dynamic access using generated strings are scenarios where you know that > every property starts with "str_" and run code like: > > var foo:String = bar["str_" + i]; > > GCC isn't smart enough to handle this. > > Dot-path Binding Expressions are where you want to use data binding to > bind to "myModel.subObject.someProperty". GCC will just look at the > entire string and since it doesn't match any property it will rename > myModel and subObject and someProperty and the binding will fail at > runtime. > > So, AIUI, we have huge string tables in our apps for these two cases even > though 99% or even 100% of the time, your app isn't going to access those > methods and properties in a way that GCC can't detect. So, before we add > some user-controlled renaming, I think we should first explore a compiler > option like -no-rename where you guarantee that your app doesn't use > generated strings or dot-path binding expressions and we clear all the > @exports out of the code before sending it to GCC. > > I'll bet somewhere in the framework we do use generated strings and will > have to fix that up, but I think that should be doable. I think the > compiler could also output string literals with "." in them as separate > strings and that might solve the dot-path problem. IOW, instead of simply > outputting "myModel.subObject.someProperty", the compiler would output: > > "myModel" + "." + "subObject" + "." + "someProperty" > > I've also seen information that indicates we might be able to control or > provide hints to GCC about what it can rename such that a smarter FalconJX > could look for dynamic access and tell GCC not to rename properties in > classes it knows will be dynamically accesses and let GCC rename > everything else. > > Volunteers are welcome to do more research on leveraging and controlling > GCC renaming. I haven't made it a high priority for me. > > My 2 cents, > -Alex > >