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
>
>

Reply via email to