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