Right, but I thought we already suggested single character names for the
ROYALE_CLASS_INFO object.
To take one example:
org.apache.royale.html.supportClasses.Viewport.prototype.ROYALE_CLASS_INFO = {
names: [{ name: 'Viewport', qName:
'org.apache.royale.html.supportClasses.Viewport', kind: 'class' }], interfaces:
[org.apache.royale.core.IBead, org.apache.royale.core.IViewport] };
That would become:
org.apache.royale.html.supportClasses.Viewport.prototype.ROYALE_CLASS_INFO = {
n: [{ n: 'Viewport', q: 'org.apache.royale.html.supportClasses.Viewport', k:
'class' }], i: [org.apache.royale.core.IBead, org.apache.royale.core.IViewport]
};
I’m pretty sure that’s enough to prevent renaming (because the closure compiler
does not rename single character variable names). If I’m wrong, we could always
output something like this:
org.apache.royale.html.supportClasses.Viewport.prototype.ROYALE_CLASS_INFO = {
'n': [{ 'n': 'Viewport', 'q': 'org.apache.royale.html.supportClasses.Viewport',
'k': 'class' }], 'i': [org.apache.royale.core.IBead,
org.apache.royale.core.IViewport] };
Am I missing something?
Harbs
> On Dec 12, 2018, at 12:32 AM, Alex Harui <[email protected]> wrote:
>
> ROYALE_CLASS_INFO is a dynamic object. There is no class definition for it,
> which means that its field names can be renamed.
>
> The whole point of modules is to load classes that aren't in the main app so
> that the main app loads faster. So, if you have
>
> MainApp.mxml
> <mx:Application>
> <mx:ModuleLoader url="MyModule" />
> </mx:Application>
>
> MyModule.mxml
> <mx:Module>
> </mx:Module>
>
> The Language.is <http://language.is/> function linked into Main app might be
> checking for ROYALE_CLASS_INFO.interfaces and Application class will have a
> ROYALE_CLASS_INFO.interfaces property. But Module might have
> ROYALE_CLASS_INFO.i instead of interfaces. And thus Language.is
> <http://language.is/> will not work on classes in the module. It depends on
> what other code is in the main app. It appears that use of Reflection.SWC's
> TypeDefinition in the main app tells the minifier to not minify the
> "interfaces" property. Which means that any code an app developer might add
> to the app could change the minification of ROYALE_CLASS_INFO, or any other
> dynamic object.
>
> I'm trying to figure out why the minifier thinks the use of "interfaces" in
> TypeDefinition matters but other attempts I've tried to force the minifier to
> not rename "interfaces" in the module have not worked.
>
> HTH,
> -Alex
>
> On 12/11/18, 2:19 PM, "Harbs" <[email protected]
> <mailto:[email protected]>> wrote:
>
> I’m still not getting the connection to ROYALE_CLASS_INFO.
>
> Can you explain to me in pseudo-code the problem with that? Why does a
> dynamic object have ROYALE_CLASS_INFO at all?
>
>> On Dec 12, 2018, at 12:16 AM, Alex Harui <[email protected]> wrote:
>>
>> I'm not sure why you think it is theoretical. For sure, in TDF, the module
>> is not loading because ROYALE_CLASS_INFO is minified differently in the main
>> app than the module. Any dynamic objects shared across compilations are at
>> risk of being renamed differently. I'm chasing down a way to control it.
>>
>> We do have control over the names of classes and properties to guarantee
>> they are the same in the app and module. It is just these dynamic object
>> keys that we don't yet have control over.
>>
>> We do have the option of defining a class for ROYALE_CLASS_INFO, but then it
>> will never minify. I like the fact that it can minify without us having to
>> use shortnames. It makes our debug code more readable and doesn't waste
>> space in small apps. Adding a class definition for ROYALE_CLASS_INFO would
>> further add overhead to small apps.
>>
>> My 2 cents,
>> -Alex
>>
>> On 12/11/18, 2:06 PM, "Harbs" <[email protected]
>> <mailto:[email protected]> <mailto:[email protected]
>> <mailto:[email protected]>>> wrote:
>>
>> In fact, in looking through the framework code so far, the only place I’ve
>> found variable names not quoted (in JS compatible code) so far was in
>> CSSUtils where we have a colorMap. I’m pretty sure the colorMap will not
>> work after minification because the color names will not match…
>>
>>> On Dec 12, 2018, at 12:01 AM, Harbs <[email protected]
>>> <mailto:[email protected]>> wrote:
>>>
>>> Hi Carlos,
>>>
>>> We’re only discussing dynamic objects. How many of those do you have in
>>> your applications? I doubt there’s much difference in performance due to
>>> minification of dynamic objects.
>>>
>>> In *all* our framework code we have dynamic object instantiation in 435
>>> places including TLF, Spark and MX classes. Without those packages, I’m
>>> estimating it’s a small fraction of that and probably most of the dynamic
>>> objects are hash maps where they don’t benefit from minification anyway.
>>>
>>> The vast majority of the cases where you’re using dynamic objects in
>>> production code you don’t want the names minified either (i.e. API calls
>>> and uses of JSON).
>>>
>>> I think that most of this discussion is more theoretical than practical
>>> considerations.
>>>
>>> My $0.02,
>>> Harbs
>>>
>>>> On Dec 11, 2018, at 11:26 PM, Carlos Rovira <[email protected]
>>>> <mailto:[email protected]>> wrote:
>>>>
>>>> Hi,
>>>>
>>>> I'm still not using modules. I left that for now until we complete the
>>>> first phase in our project, but will be using (hopefully) around February.
>>>>
>>>> So right now we're only using minification, that seems not only to reduce
>>>> the size of the build, but release mode performs faster, and I think is
>>>> due, in part, to minify.
>>>>
>>>> So, IMHO, as a user, I don't like A). Can't think of a solution, since is
>>>> not my zone of expertise, and sure you guys found a good solution after
>>>> all. Just want to say that as a user, is importante both things: have
>>>> modules (and hope we could link as well with routing like people do in
>>>> other current techs like React and Angular to get a powerful solution for
>>>> SPAs) and have minification, since IMO, the resultant js-release build has
>>>> many, many advantages, not only in performance and size but as well in
>>>> obfuscation, and for me is like our "binary output code".
>>>>
>>>> Sorry to not be able to give any suggestion, but maybe as well an opinion
>>>> of use is as well valuable.
>>>>
>>>> just my 2
>>>>
>>>>
>>>> El mar., 11 dic. 2018 a las 21:24, Alex Harui (<[email protected]
>>>> <mailto:[email protected]>>)
>>>> escribió:
>>>>
>>>>> Thinking about it more, -js-dynamic-access probably won't help. We don't
>>>>> want to compile our SWCs with that option on and thus turn off
>>>>> minification
>>>>> of these field names always if we can help it.
>>>>>
>>>>> Even a directive per occurrence won't help either. Whether a field name
>>>>> is renamed is still dependent on what other code is in the compilation.
>>>>>
>>>>> The problem is better described as trying to find a way to control what
>>>>> field names get renamed in more than one compilation, given that there is
>>>>> pre-transpiled code that allows renaming. When building modules, we
>>>>> already require using Closure Compiler options that output the renaming
>>>>> maps of the main app so that UIBase is given the same short name in all
>>>>> minifications. But there is no way to dictate that for field names as far
>>>>> as I can tell.
>>>>>
>>>>> -Alex
>>>>>
>>>>> On 12/11/18, 11:32 AM, "Harbs" <[email protected]
>>>>> <mailto:[email protected]>> wrote:
>>>>>
>>>>> I vote for A.
>>>>>
>>>>> We can also do B which would require manually changing all access to
>>>>> brackets and quote all names in object literals.
>>>>>
>>>>> I might be nice to add some comment decorations to enable/disable
>>>>> -js-dynamic-access on a case-by-case basis, but I think it’s reasonable to
>>>>> have a global on/off requirement. I’m already doing this for a library I
>>>>> wrote which has a lot of dynamic data structures which does not survive
>>>>> minification and the results are fine.
>>>>>
>>>>> My $0.02,
>>>>> Harbs
>>>>>
>>>>>> On Dec 11, 2018, at 8:47 PM, Alex Harui <[email protected]
>>>>>> <mailto:[email protected]>>
>>>>> wrote:
>>>>>>
>>>>>> IMO, some folks will want to rely on minification of object field
>>>>> names so save space. I think -js-dynamic-access blocks minification.
>>>>>>
>>>>>> So, to try to pose the problem another way, you can rely on
>>>>> minification object field names if you are building a single-js-file app,
>>>>> but as soon as you start using modules, things may break. So what should
>>>>> we tell folks?
>>>>>>
>>>>>> A) if you use modules you must turn off minification in objects with
>>>>> -js-dynamic-access
>>>>>> B) here are some ways to hack your code so you can still rely on
>>>>> minification
>>>>>> C) something else?
>>>>>>
>>>>>> We can manually rename fields in ROYALE_CLASS_INFO and other
>>>>> structures to make our code less readable in debug mode but save space in
>>>>> release mode, but that does not solve the general case problem. Folks may
>>>>> have other objects in their apps and modules that work until you add some
>>>>> code to one of the projects that changes which object fields get renamed.
>>>>>>
>>>>>> -Alex
>>>>>>
>>>>>> On 12/11/18, 9:31 AM, "Harbs" <[email protected]
>>>>>> <mailto:[email protected]>> wrote:
>>>>>>
>>>>>> I’m not following why this is the same point.
>>>>>>
>>>>>> I’m using -js-dynamic-access-unknown-members=true to handle this
>>>>> kind of problem. It works flawlessly…
>>>>>>
>>>>>> I’d personally argue that true should be the default, but whether
>>>>> the default is true or not, we do have an option to deal with these kinds
>>>>> of data structures.
>>>>>>
>>>>>>> On Dec 11, 2018, at 6:39 PM, Alex Harui <[email protected]
>>>>>>> <mailto:[email protected]>>
>>>>> wrote:
>>>>>>>
>>>>>>> Yes, we can use our own short names in code we generate, but that's
>>>>> not really the point.
>>>>>>>
>>>>>>> The point is that any plain object field can be renamed based on
>>>>> other code in the compile. So if you just have:
>>>>>>>
>>>>>>> Var obj:Object = { harbs: 1};
>>>>>>> Public static function foo()
>>>>>>> {
>>>>>>> Trace(obj.harbs);
>>>>>>> }
>>>>>>>
>>>>>>> Use of foo() in one compile may result in harbs being renamed, and
>>>>> another wouldn't. And that poses a problem when data structures are
>>>>> shared
>>>>> between compiled outputs.
>>>>>>>
>>>>>>> This is a natural way to write AS, but the JS results when minified
>>>>> and shared between app and modules can fail. So what restrictions should
>>>>> we place if any on how folks use plain objects?
>>>>>>>
>>>>>>> HTH,
>>>>>>> -Alex
>>>>>>>
>>>>>>> On 12/11/18, 7:36 AM, "Harbs" <[email protected]
>>>>>>> <mailto:[email protected]>> wrote:
>>>>>>>
>>>>>>> I was about to make the same suggestion. We can use “I” for
>>>>> interfaces, “c” for class, “k” for kind, “n” for names. etc.
>>>>>>>
>>>>>>>> On Dec 11, 2018, at 2:52 PM, Frost, Andrew <[email protected]
>>>>>>>> <mailto:[email protected]>>
>>>>> wrote:
>>>>>>>>
>>>>>>>> Hi
>>>>>>>>
>>>>>>>> Not sure that I fully understand this but would a valid compromise
>>>>> be something where the field name isn't renamed at all automatically, but
>>>>> we just change it in the JS generation code to be "i" rather than
>>>>> "interfaces", and update the Language is/as functions to work with this
>>>>> property name? Not sure whether it would work and I don't know whether the
>>>>> Reflection stuff would then need to change too, but if this is all in the
>>>>> generated outputs and/or the framework's own code then it shouldn't be
>>>>> something that the end user would bother about..
>>>>>>>>
>>>>>>>> thanks
>>>>>>>>
>>>>>>>> Andrew
>>>>>>>>
>>>>>>>>
>>>>>>>> -----Original Message-----
>>>>>>>> From: Alex Harui [mailto:[email protected]
>>>>>>>> <mailto:[email protected]>]
>>>>>>>> Sent: 11 December 2018 08:32
>>>>>>>> To: [email protected] <mailto:[email protected]>
>>>>>>>> Subject: [EXTERNAL] ROYALE_CLASS_INFO, renaming, modules, Objects
>>>>>>>>
>>>>>>>> I spent some time today trying to get Tour De Flex to run in
>>>>> production mode with the main app and modules being separately minified.
>>>>>>>>
>>>>>>>> I've fixed a few things here and there, but an interesting issue I
>>>>> ran into has to do with the plain object we use in ROYALE_CLASS_INFO (and
>>>>> will apply to other objects).
>>>>>>>>
>>>>>>>> The ROYALE_CLASS_INFO is generated on each class and has a "names"
>>>>> property and an optional "interfaces" property. An example is:
>>>>>>>>
>>>>>>>>
>>>>> org.apache.royale.html.beads.models.PanelModel.prototype.ROYALE_CLASS_INFO
>>>>> = { names: [{ name: 'PanelModel', qName:
>>>>> 'org.apache.royale.html.beads.models.PanelModel', kind: 'class' }],
>>>>> interfaces: [org.apache.royale.core.IBead,
>>>>> org.apache.royale.core.IPanelModel] };
>>>>>>>>
>>>>>>>> Because the field names are not quoted, then in most output, the
>>>>> field name "interfaces" is renamed and all code referencing this field is
>>>>> renamed as well. This is good because it means that you don't have to
>>>>> download the word "interfaces" once per-class. Instead of 10 characters,
>>>>> it
>>>>> is usually one or two. 100 classes saves you about 900 bytes.
>>>>>>>>
>>>>>>>> However, it turns out that in Tour De Flex, the main app uses
>>>>> Reflection and Reflection uses a quoted 'interfaces' string and thus, the
>>>>> field name 'interfaces' in ROYALE_CLASS_INFO isn't renamed, but in most
>>>>> modules "interfaces" is renamed since no other code in the module has a
>>>>> quoted string for 'interfaces'. But that means that when a module loads,
>>>>> the Language.is/as <http://language.is/as> won't work since classes in
>>>>> the main app are using
>>>>> "interfaces" but the classes in the module are using some short name.
>>>>>>>>
>>>>>>>> One solution is to always quote that field in the compiler output
>>>>> and Language is/as so it doesn't get renamed, but that means that field
>>>>> will never get renamed and you lose saving those bytes.
>>>>>>>>
>>>>>>>> Another is let folks figure out their own workarounds, by adding
>>>>> some code that will prevent the renaming in the modules.
>>>>>>>>
>>>>>>>> Other ideas are welcome. I'm done for tonight.
>>>>>>>>
>>>>>>>> Thoughts?
>>>>>>>> -Alex
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>
>>>> --
>>>> Carlos Rovira
>>>> https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fabout.me%2Fcarlosrovira&data=02%7C01%7Caharui%40adobe.com%7C2c36443f61b4436324ee08d65fb6a252%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636801635412696785&sdata=DwG2KMwX7oKIaag1NeuP%2BnNwPp4VD7amvdLaKmPQ7H8%3D&reserved=0
>>>>
>>>> <https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fabout.me%2Fcarlosrovira&data=02%7C01%7Caharui%40adobe.com%7C2c36443f61b4436324ee08d65fb6a252%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636801635412696785&sdata=DwG2KMwX7oKIaag1NeuP%2BnNwPp4VD7amvdLaKmPQ7H8%3D&reserved=0><https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fabout.me%2Fcarlosrovira&data=02%7C01%7Caharui%40adobe.com%7C2c36443f61b4436324ee08d65fb6a252%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636801635412696785&sdata=DwG2KMwX7oKIaag1NeuP%2BnNwPp4VD7amvdLaKmPQ7H8%3D&reserved=0
>>>>
>>>> <https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fabout.me%2Fcarlosrovira&data=02%7C01%7Caharui%40adobe.com%7C2c36443f61b4436324ee08d65fb6a252%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636801635412696785&sdata=DwG2KMwX7oKIaag1NeuP%2BnNwPp4VD7amvdLaKmPQ7H8%3D&reserved=0>>