You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@royale.apache.org by Josh Tynjala <jo...@bowlerhat.dev> on 2021/05/24 20:31:57 UTC

Compiler options for reducing release build size of Royale projects (Part 2)

Back in November, I shared a summary of some of the work that I've been
doing on reducing the size of release builds generated by the Royale
compiler. Essentially, I've been trying to ensure that we could take better
advantage of Closure compiler's advanced optimizations for minification,
which includes removing dead code and renaming symbols so that they have
shorter names.

Since then, I've made some more improvements to the Royale compiler, which
will allow even more optimization. I figured that it is a good time to
share my latest results.

To fully understand the context of today's post, I recommend reviewing the
introduction that I wrote for my earlier post (you can stop once I start
talking about the results). Here's the link to the archive:

https://lists.apache.org/thread.html/rf53d200969d795a15bda5d6635b904d89fa7f6af151df5dca15ccbbb%40%3Cdev.royale.apache.org%3E

Last time, in my final set of results, some public symbols were allowed to
be renamed in the release build, but some were not. If I tried to rename
all public symbols, it would cause parts of the apps to stop working
correctly. My work since then has been finding ways to ensure that more
public symbols can be renamed safely.

What I determined is that the way that we encode MXML data in JavaScript
results in a lot of dynamically setting properties using string names,
similar to `variable["propName"] = value`. Setting properties dynamically
is generally bad when minimizing with Closure compiler because it won't
understand that it needs to keep those properties, and it may remove them
as dead code (even though it's not dead code), or it may change their names
(while our code still uses the original names).

Luckly, our MXML data in JS is well-structured, so it's possible to walk
the JS tree when creating the release build and extract names that are used
dynamically in MXML. Then, we can pass those names to Closure compiler
manually. Basically, we're extending the Closure compiler with an extra
analysis step that has specialized knowledge of Royale. This allows us to
rename more public symbols because we can exclude the ones that we know
cannot be renamed).

I added a new compiler option, *prevent-rename-mxml-symbol-references*,
which defaults to true. You will probably never want to change this to
false, but the option is there, if anyone ever determines that it is needed
in some edge case.

Okay, now to the results. I built the same four app projects as last time.

I used the following commits, if anyone wants to try reproducing on their
own computer:

royale-compiler: 65805281ea898b3a0225922f5956c864f810c423
royale-asjs: fab5f5444e0e9ee7f8f59e5cf1d4b1144a31025e
spectrum-royale: acf4007fa322d61e1d0ae874e4c2009f8645654c

==========
Baseline: royale-compiler 0.9.7
==========

HelloWorld: 71 KB
ASDoc: 237 KB
TourDeJewel: 1125 KB
SpectrumBrowser: 944 KB

As with my previous post, I built all of the example projects with the
Royale 0.9.7 compiler first. However, I built them with the latest
framework code. This ensures that only the differences in the compiler are
being compared, and we don't have extra noise from differences in the
framework code.

-----

Now, let's see some results with the latest compiler.

All results below include the +/- difference in KB and %. These values are
always in comparison to the baseline numbers above.

==========
Result 1: Latest compiler with default options
==========

HelloWorld: 87 KB (+16 KB / +23%)
ASDoc: 261 KB (+24 KB / +10%)
TourDeJewel: 1159 KB (+34 KB / +3%)
SpectrumBrowser: 980 KB (+36 KB / +4%)

As with the previous post, the increase in file size here is expected. The
latest compiler fixes some bugs that were present in 0.9.7 that caused
certain symbols to be renamed/removed when they should not have been.

==========
Result 2: Disable symbol exports and allow non-public symbols to be renamed
==========

HelloWorld: 74 KB (+3 KB / +4%)
ASDoc: 226 KB (-11 KB / -5%)
TourDeJewel: 966 KB (-159 KB / -14%)
SpectrumBrowser: 897 KB (-47 KB / -5%)

Compiler options used:
*-export-public-symbols=false*
*-prevent-rename-protected-symbols=false*
*-prevent-rename-internal-symbols=false*

These results are consistent with a similar test from my previous post. I
included it to show that nothing has changed, and to have an intermediate
step between the default options and the full optimizations.

==========
Result 3: Allow public symbols to be renamed too
==========

HelloWorld: 66 KB (-5 KB / -7%)
ASDoc: N/A
TourDeJewel: N/A
SpectrumBrowser: 857 KB (-87 KB / -9%)

Compiler options used:
-export-public-symbols=false
-prevent-rename-protected-symbols=false
-prevent-rename-internal-symbols=false
*-prevent-rename-public-symbols=false*

This is a compiler option that I didn't include in the tests last time
because renaming all public symbols broke every app before. Now that the
Royale compiler walks the MXML data tree, it's possible to allow renaming
of public symbols in some apps (but not all, for reasons I will explain). *This
combination of compiler options provides the largest possible file size
savings in release builds.*

You'll notice that ASDoc and TourDeJewel are marked N/A. This is because
they use the ConstantBinding class, which sets up bindings dynamically.

<js:ConstantBinding sourceID="listModel" sourcePropertyName="iconListData"
destinationPropertyName="dataProvider"/>

When compiled to JS, this code basically converts to this:

this[binding.destinationPropertyName] =
this[binding.sourceID][binding.sourcePropertyName];

Notice the bracket access with string values. Like I explained before,
this is something that Closure compiler cannot detect.

Technically, I could write another custom Closure compiler pass that looks
for ConstantBinding objects in the MXML data tree and extract the property
names. It wouldn't be hard, but what happens if new types of bindings are
added that work similarly? Do I just keep adding them to the compiler as
special cases? Or what if someone wants to use the compiler with a
different framework and wants to move ConstantBinding to a different
package? Do they need to modify the compiler too? It simply doesn't feel
clean to me. So, if you want to use the
-prevent-rename-public-symbols=false compiler option, I recommend avoiding
ConstantBinding. Regular bindings with curly braces {} are fully supported,
and they're what most people will be familiar with from Flex anyway.

==========
Extra Result: Allow *some* public symbols to be renamed
==========

ASDoc: 210 KB (-27 KB / -11%)
TourDeJewel: 927 KB (-198 KB / -18%)

Compiler options used:
-export-public-symbols=false
-prevent-rename-protected-symbols=false
-prevent-rename-internal-symbols=false
*-prevent-rename-public-static-methods=false*
*-prevent-rename-public-instance-methods=false*

That being said, even when using ConstantBinding or other dynamic features,
it may be possible to rename a subset of public symbols. Most commonly,
public methods are usually safe to rename because most people don't try to
call methods dynamically. This final extra test is consistent with a
similar result from my previous post.

That was really long, so thank you for reading, if you made it to the end!

--
Josh Tynjala
Bowler Hat LLC <https://bowlerhat.dev>

RE: Compiler options for reducing release build size of Royale projects (Part 2)

Posted by Yishay Weiss <yi...@hotmail.com>.
*public access methods

From: Yishay Weiss<ma...@hotmail.com>
Sent: Tuesday, May 25, 2021 9:07 AM
To: dev@royale.apache.org<ma...@royale.apache.org>
Subject: RE: Compiler options for reducing release build size of Royale projects (Part 2)

Hi Josh,

I still haven’t wrapped my head around all of this but thanks for the informative post. Does this somehow mean public vars are now always safe to use as opposed to having to covert them to public methods?

From: Josh Tynjala<ma...@bowlerhat.dev>
Sent: Monday, May 24, 2021 11:32 PM
To: Apache Royale Development<ma...@royale.apache.org>
Subject: Compiler options for reducing release build size of Royale projects (Part 2)

Back in November, I shared a summary of some of the work that I've been
doing on reducing the size of release builds generated by the Royale
compiler. Essentially, I've been trying to ensure that we could take better
advantage of Closure compiler's advanced optimizations for minification,
which includes removing dead code and renaming symbols so that they have
shorter names.

Since then, I've made some more improvements to the Royale compiler, which
will allow even more optimization. I figured that it is a good time to
share my latest results.

To fully understand the context of today's post, I recommend reviewing the
introduction that I wrote for my earlier post (you can stop once I start
talking about the results). Here's the link to the archive:

https://lists.apache.org/thread.html/rf53d200969d795a15bda5d6635b904d89fa7f6af151df5dca15ccbbb%40%3Cdev.royale.apache.org%3E

Last time, in my final set of results, some public symbols were allowed to
be renamed in the release build, but some were not. If I tried to rename
all public symbols, it would cause parts of the apps to stop working
correctly. My work since then has been finding ways to ensure that more
public symbols can be renamed safely.

What I determined is that the way that we encode MXML data in JavaScript
results in a lot of dynamically setting properties using string names,
similar to `variable["propName"] = value`. Setting properties dynamically
is generally bad when minimizing with Closure compiler because it won't
understand that it needs to keep those properties, and it may remove them
as dead code (even though it's not dead code), or it may change their names
(while our code still uses the original names).

Luckly, our MXML data in JS is well-structured, so it's possible to walk
the JS tree when creating the release build and extract names that are used
dynamically in MXML. Then, we can pass those names to Closure compiler
manually. Basically, we're extending the Closure compiler with an extra
analysis step that has specialized knowledge of Royale. This allows us to
rename more public symbols because we can exclude the ones that we know
cannot be renamed).

I added a new compiler option, *prevent-rename-mxml-symbol-references*,
which defaults to true. You will probably never want to change this to
false, but the option is there, if anyone ever determines that it is needed
in some edge case.

Okay, now to the results. I built the same four app projects as last time.

I used the following commits, if anyone wants to try reproducing on their
own computer:

royale-compiler: 65805281ea898b3a0225922f5956c864f810c423
royale-asjs: fab5f5444e0e9ee7f8f59e5cf1d4b1144a31025e
spectrum-royale: acf4007fa322d61e1d0ae874e4c2009f8645654c

==========
Baseline: royale-compiler 0.9.7
==========

HelloWorld: 71 KB
ASDoc: 237 KB
TourDeJewel: 1125 KB
SpectrumBrowser: 944 KB

As with my previous post, I built all of the example projects with the
Royale 0.9.7 compiler first. However, I built them with the latest
framework code. This ensures that only the differences in the compiler are
being compared, and we don't have extra noise from differences in the
framework code.

-----

Now, let's see some results with the latest compiler.

All results below include the +/- difference in KB and %. These values are
always in comparison to the baseline numbers above.

==========
Result 1: Latest compiler with default options
==========

HelloWorld: 87 KB (+16 KB / +23%)
ASDoc: 261 KB (+24 KB / +10%)
TourDeJewel: 1159 KB (+34 KB / +3%)
SpectrumBrowser: 980 KB (+36 KB / +4%)

As with the previous post, the increase in file size here is expected. The
latest compiler fixes some bugs that were present in 0.9.7 that caused
certain symbols to be renamed/removed when they should not have been.

==========
Result 2: Disable symbol exports and allow non-public symbols to be renamed
==========

HelloWorld: 74 KB (+3 KB / +4%)
ASDoc: 226 KB (-11 KB / -5%)
TourDeJewel: 966 KB (-159 KB / -14%)
SpectrumBrowser: 897 KB (-47 KB / -5%)

Compiler options used:
*-export-public-symbols=false*
*-prevent-rename-protected-symbols=false*
*-prevent-rename-internal-symbols=false*

These results are consistent with a similar test from my previous post. I
included it to show that nothing has changed, and to have an intermediate
step between the default options and the full optimizations.

==========
Result 3: Allow public symbols to be renamed too
==========

HelloWorld: 66 KB (-5 KB / -7%)
ASDoc: N/A
TourDeJewel: N/A
SpectrumBrowser: 857 KB (-87 KB / -9%)

Compiler options used:
-export-public-symbols=false
-prevent-rename-protected-symbols=false
-prevent-rename-internal-symbols=false
*-prevent-rename-public-symbols=false*

This is a compiler option that I didn't include in the tests last time
because renaming all public symbols broke every app before. Now that the
Royale compiler walks the MXML data tree, it's possible to allow renaming
of public symbols in some apps (but not all, for reasons I will explain). *This
combination of compiler options provides the largest possible file size
savings in release builds.*

You'll notice that ASDoc and TourDeJewel are marked N/A. This is because
they use the ConstantBinding class, which sets up bindings dynamically.

<js:ConstantBinding sourceID="listModel" sourcePropertyName="iconListData"
destinationPropertyName="dataProvider"/>

When compiled to JS, this code basically converts to this:

this[binding.destinationPropertyName] =
this[binding.sourceID][binding.sourcePropertyName];

Notice the bracket access with string values. Like I explained before,
this is something that Closure compiler cannot detect.

Technically, I could write another custom Closure compiler pass that looks
for ConstantBinding objects in the MXML data tree and extract the property
names. It wouldn't be hard, but what happens if new types of bindings are
added that work similarly? Do I just keep adding them to the compiler as
special cases? Or what if someone wants to use the compiler with a
different framework and wants to move ConstantBinding to a different
package? Do they need to modify the compiler too? It simply doesn't feel
clean to me. So, if you want to use the
-prevent-rename-public-symbols=false compiler option, I recommend avoiding
ConstantBinding. Regular bindings with curly braces {} are fully supported,
and they're what most people will be familiar with from Flex anyway.

==========
Extra Result: Allow *some* public symbols to be renamed
==========

ASDoc: 210 KB (-27 KB / -11%)
TourDeJewel: 927 KB (-198 KB / -18%)

Compiler options used:
-export-public-symbols=false
-prevent-rename-protected-symbols=false
-prevent-rename-internal-symbols=false
*-prevent-rename-public-static-methods=false*
*-prevent-rename-public-instance-methods=false*

That being said, even when using ConstantBinding or other dynamic features,
it may be possible to rename a subset of public symbols. Most commonly,
public methods are usually safe to rename because most people don't try to
call methods dynamically. This final extra test is consistent with a
similar result from my previous post.

That was really long, so thank you for reading, if you made it to the end!

--
Josh Tynjala
Bowler Hat LLC <https://bowlerhat.dev>



Re: Compiler options for reducing release build size of Royale projects (Part 2)

Posted by Harbs <ha...@gmail.com>.
Yes. (but it usually goes together with the original size)

> On Dec 29, 2021, at 7:26 PM, Alex Harui <ah...@adobe.com.INVALID> wrote:
> 
> It is probably worth making sure everyone is in agreement that this exercise is measured by gzipped output of the Google Compiler's optimized/minified results.  So it is perfectly fine if the .js file in bin/js-release gets bigger as long as it gets smaller when you zip it.


Re: Compiler options for reducing release build size of Royale projects (Part 2)

Posted by Alex Harui <ah...@adobe.com.INVALID>.
FWIW, there is a -skip-transpile option for the compiler.  First, you compile your app without that option to get the bin/js-debug.  Then you can muck with the JS in bin/js-debug.  Then compile with -skip-transpile and it should just take your bin/js-debug and send it to the Google Compiler to generate the bin/js-release.

It is probably worth making sure everyone is in agreement that this exercise is measured by gzipped output of the Google Compiler's optimized/minified results.  So it is perfectly fine if the .js file in bin/js-release gets bigger as long as it gets smaller when you zip it.

HTH,
-Alex

On 12/29/21, 3:11 AM, "Harbs" <ha...@gmail.com> wrote:

    source-map-explorer looks cool. Never tried it.

    I’m not sure how useful that tool is for Royale other than seeing which classes were included. The issue here is cumulative size of the js files.

    The saving for removing class names is a linear savings directly related to the number of classes you use.

    I happen to know that the class names are only used by CSSSimpleStylesImpl in my app. That means the minified code which contains the class names is totally unnecessary if we can resolve the CSSSimpleStylesImpl lookup. To test how much of a difference it made, I deleted all the names from the minified code and gzipped the file. Just removing the class names resulted in about a 10KB reduction *after* gzipping for a 600KB+ gzipped js file. That’s about a 6% reduction for just the names. Not staggering, but significant.

    Besides the size, it results in “cleaner” code, and the app structure is not obvious in the minified code. That’s a plus in my mind.

    > On Dec 29, 2021, at 11:44 AM, Edward Stangler <es...@bradmark.com> wrote:
    > 
    > [I wrote this several weeks ago but didn't send it out.  The gist of it is that I don't think it's worth removing class names.]
    > 
    > 
    > Which tools are you using to direct your investigation into reducing sizes?
    > 
    > 
    > For your test case below:
    > 
    > 87,824 regular release mode
    > 65,727 optimized (with your optimization switches)
    > ------
    > 22,097 bytes smaller (25% savings)
    > (and SWF went up a few bytes)
    > 
    > < 3,600 bytes (5.5% of optimized size) is in full names at top
    > 
    > 
    > For a basic Spark skin app (from issue #995):
    > 
    > 811,560 - regular release mode
    > 631,789 - optimized (with your optimization switches)
    > -------
    > 179,771 bytes smaller (22% savings)
    > 
    > < 20,000 bytes (3% of optimized size) is in full names at top
    > 
    > For comparison, just the mentions of "declaredBy" (part of Reflection) take > 20,000 bytes (and that doesn't even include the other parts of the Reflection metadata, which are not used in that skin app).
    > 
    > 
    > The source-map-explorer output for the Spark skin app looks like this:
    > 
    > 
    > 
    > (The one for your test case below--not shown--overemphasizes Language.js (~10KB), since the file sizes are so small (~60KB);  the one above is more representative of inefficiencies.)
    > 
    > 
    > How will class names reduce the size significantly?
    > 
    > 
    > 
    > On 12/1/2021 12:15 PM, Harbs wrote:
    >> I suspect that the following is happening:
    >> 
    >> 1. Language.as uses ROYALE_CLASS_INFO to find interfaces.
    >> 2. That makes Closure Compiler assume ROYALE_CLASS_INFO is needed.
    >> 3. All the info from ROYALE_CLASS_INFO including the class name and qname is preserved.
    >> 
    >> Perhaps we should have two variables:
    >> 1. ROYALE_CLASS_INFO for the name and qname
    >> 2. ROYALE_INTERFACE_INFO for the interface dependency
    >> 
    >> That should free up ROYALE_CLASS_INFO to be removed unless Reflection is used.
    >> 
    >> Thoughts?
    >> 
    >>> On Dec 1, 2021, at 7:50 PM, Harbs <ha...@gmail.com> <ma...@gmail.com> wrote:
    >>> 
    >>> It looks to me like that’s it.
    >>> 
    >>> We have this included in the minified code which should not be there:
    >>> 
    >>> ke.prototype.g={names:[{name:'IStyleObject',h:fb,kind:k}]};
    >>> 
    >>>> On Dec 1, 2021, at 7:46 PM, Harbs <ha...@gmail.com> <ma...@gmail.com> wrote:
    >>>> 
    >>>> Hmm. Maybe.
    >>>> 
    >>>> Greg, I think that’s your area of expertise.
    >>>> 
    >>>>> On Dec 1, 2021, at 7:45 PM, Josh Tynjala <jo...@bowlerhat.dev> <ma...@bowlerhat.dev> wrote:
    >>>>> 
    >>>>> Could those be the qname strings added to the ROYALE_CLASS_INFO object?
    >>>>> 
    >>>>> For example, I assume that this one:
    >>>>> 
    >>>>> fb='org.apache.royale.core.IStyleObject'
    >>>>> 
    >>>>> Comes from here:
    >>>>> 
    >>>>> /**
    >>>>> * Metadata
    >>>>> *
    >>>>> * @type {Object.<string, Array.<Object>>}
    >>>>> */
    >>>>> org.apache.royale.core.IStyleObject.prototype.ROYALE_CLASS_INFO = { names:
    >>>>> [{ name: 'IStyleObject', qName: 'org.apache.royale.core.IStyleObject',
    >>>>> kind: 'interface' }] };
    >>>>> 
    >>>>> I'm not super familiar with the reflection system, so that's just a guess.
    >>>>> 
    >>>>> --
    >>>>> Josh Tynjala
    >>>>> Bowler Hat LLC <https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbowlerhat.dev%2F&amp;data=04%7C01%7Caharui%40adobe.com%7Cb75f01684b3247865f8c08d9cabbe84d%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637763731122048933%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=Uh8%2BH9iI7ZPOoNDunArfhhWIIc0iuIx5oLGhmKGiUho%3D&amp;reserved=0> <https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbowlerhat.dev%2F&amp;data=04%7C01%7Caharui%40adobe.com%7Cb75f01684b3247865f8c08d9cabbe84d%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637763731122048933%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=Uh8%2BH9iI7ZPOoNDunArfhhWIIc0iuIx5oLGhmKGiUho%3D&amp;reserved=0>
    >>>>> 
    >>>>> 
    >>>>> On Wed, Dec 1, 2021 at 9:25 AM Harbs <ha...@gmail.com> <ma...@gmail.com> wrote:
    >>>>> 
    >>>>>> Maybe I’m missing a compiler option, but I compiled this:
    >>>>>> 
    >>>>>> <?xml version="1.0" encoding="utf-8"?>
    >>>>>> <js:Application xmlns:fx="https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fns.adobe.com%2Fmxml%2F2009&amp;data=04%7C01%7Caharui%40adobe.com%7Cb75f01684b3247865f8c08d9cabbe84d%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637763731122048933%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=i2knXVhi4Tpda1cBVo0uWsC%2FwgMW0O%2FxaiSq9JjzQLg%3D&amp;reserved=0" <https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fns.adobe.com%2Fmxml%2F2009&amp;data=04%7C01%7Caharui%40adobe.com%7Cb75f01684b3247865f8c08d9cabbe84d%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637763731122048933%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=i2knXVhi4Tpda1cBVo0uWsC%2FwgMW0O%2FxaiSq9JjzQLg%3D&amp;reserved=0>
    >>>>>>              xmlns:js="library://ns.apache.org/royale/basic"
    >>>>>>              applicationComplete="onComplete()">
    >>>>>>  <fx:Script>
    >>>>>>      <![CDATA[
    >>>>>>          private function onComplete():void{
    >>>>>>              trace("foo");
    >>>>>>          }
    >>>>>>      ]]>
    >>>>>>  </fx:Script>
    >>>>>>  <js:valuesImpl>
    >>>>>>      <js:SimpleCSSValuesImpl />
    >>>>>>  </js:valuesImpl>
    >>>>>>  <js:initialView>
    >>>>>>      <js:View>
    >>>>>>          <js:Label text="ID" id="id1" localId="id1" />
    >>>>>>      </js:View>
    >>>>>>  </js:initialView>
    >>>>>> </js:Application>
    >>>>>> 
    >>>>>> with this:
    >>>>>> 
    >>>>>> {
    >>>>>>  "config": "royale",
    >>>>>>  "compilerOptions": {
    >>>>>>      "debug": true,
    >>>>>>      "targets": ["JSRoyale"],
    >>>>>>      "source-map": true,
    >>>>>>      "remove-circulars": true
    >>>>>>  },
    >>>>>>  "additionalOptions": "-js-output-optimization=skipAsCoercions
    >>>>>> -allow-abstract-classes=true -js-vector-emulation-class=Array
    >>>>>> -js-vector-index-checks=false -js-complex-implicit-coercions=false
    >>>>>> -export-public-symbols=false -prevent-rename-protected-symbols=false
    >>>>>> -prevent-rename-public-static-methods=false
    >>>>>> -prevent-rename-public-instance-methods=false
    >>>>>> -prevent-rename-public-static-variables=false
    >>>>>> -prevent-rename-public-instance-variables=false
    >>>>>> -prevent-rename-public-instance-accessors=false",
    >>>>>>  "files":
    >>>>>>  [
    >>>>>>      "src/test_project.mxml"
    >>>>>>  ]
    >>>>>> }
    >>>>>> 
    >>>>>> And got this at the top of the minified code:
    >>>>>> 
    >>>>>> 
    >>>>>> var aa='Error #1034: Type Coercion failed: cannot convert
    >>>>>> ',ba='applicationComplete',ca='array',da='backgroundImage',ea='border-box',fa='childrenAdded',f='class',ha='deferredSizeHandler',ia='explicitHeightChanged',ja='explicitWidthChanged',h='function',ka='handleInitComplete',la='handleSizeChange',ma='heightChanged',na='inherit',oa='initComplete',k='interface',pa='number',qa='object',ra='org.apache.royale.core.Application',sa='org.apache.royale.core.ApplicationBase',ta='org.apache.royale.core.Bead',
    >>>>>> 
    >>>>>> ua='org.apache.royale.core.BeadViewBase',va='org.apache.royale.core.DispatcherBead',wa='org.apache.royale.core.ElementWrapper',xa='org.apache.royale.core.GroupBase',ya='org.apache.royale.core.HTMLElementWrapper',za='org.apache.royale.core.IApplicationView',Aa='org.apache.royale.core.IBead',Ba='org.apache.royale.core.IBeadController',Ca='org.apache.royale.core.IBeadLayout',Da='org.apache.royale.core.IBeadModel',Ea='org.apache.royale.core.IBeadView',Fa='org.apache.royale.core.IBorderPaddingMarginValuesImpl',
    >>>>>> 
    >>>>>> Ga='org.apache.royale.core.ICSSImpl',Ha='org.apache.royale.core.IChild',Ia='org.apache.royale.core.IContainer',Ja='org.apache.royale.core.IContentViewHost',Ka='org.apache.royale.core.IDocument',La='org.apache.royale.core.IFlexInfo',Ma='org.apache.royale.core.IId',Na='org.apache.royale.core.IInitialViewApplication',Oa='org.apache.royale.core.ILayoutChild',Pa='org.apache.royale.core.ILayoutHost',Qa='org.apache.royale.core.ILayoutParent',Ra='org.apache.royale.core.ILayoutView',Sa='org.apache.royale.core.IMXMLDocument',
    >>>>>> 
    >>>>>> Ta='org.apache.royale.core.IMeasurementBead',Ua='org.apache.royale.core.IParent',Va='org.apache.royale.core.IParentIUIBase',Wa='org.apache.royale.core.IPopUpHost',Xa='org.apache.royale.core.IPopUpHostParent',Ya='org.apache.royale.core.IRenderedObject',Za='org.apache.royale.core.IRoyaleElement',$a='org.apache.royale.core.IState',ab='org.apache.royale.core.IStatesImpl',bb='org.apache.royale.core.IStatesObject',cb='org.apache.royale.core.IStrand',db='org.apache.royale.core.IStrandWithModel',eb='org.apache.royale.core.IStrandWithModelView',
    >>>>>> 
    >>>>>> fb='org.apache.royale.core.IStyleObject',gb='org.apache.royale.core.IStyleableObject',hb='org.apache.royale.core.IUIBase',ib='org.apache.royale.core.IValuesImpl',jb='org.apache.royale.core.LayoutBase',kb='org.apache.royale.core.SimpleCSSValuesImpl',lb='org.apache.royale.core.UIBase',mb='org.apache.royale.core.ValuesManager',nb='org.apache.royale.core.View',ob='org.apache.royale.core.ViewBase',pb='org.apache.royale.core.WrappedHTMLElement',qb='org.apache.royale.core.layout.EdgeData',rb='org.apache.royale.core.layout.LayoutData',
    >>>>>> 
    >>>>>> sb='org.apache.royale.core.layout.MarginData',tb='org.apache.royale.core.styles.BorderStyles',ub='org.apache.royale.events.BrowserEvent',vb='org.apache.royale.events.ElementEvents',wb='org.apache.royale.events.Event',xb='org.apache.royale.events.EventDispatcher',yb='org.apache.royale.events.IBrowserEvent',zb='org.apache.royale.events.IEventDispatcher',Ab='org.apache.royale.events.IRoyaleEvent',Bb='org.apache.royale.events.ValueChangeEvent',Cb='org.apache.royale.events.ValueEvent',Db='org.apache.royale.events.utils.EventUtils',
    >>>>>> Eb='org.apache.royale.html.Label',Fb='org.apache.royale.html.beads.GroupView',Gb='org.apache.royale.html.beads.layouts.BasicLayout',Hb='org.apache.royale.utils.CSSUtils',Ib='org.apache.royale.utils.MXMLDataInterpreter',Jb='org.apache.royale.utils.StringPadder',Kb='org.apache.royale.utils.Timer',Lb='percentHeightChanged',Mb='percentWidthChanged',Nb='resizeHandler',Ob='sizeChanged',Pb='string',Qb='test_project',Rb='viewChanged',Sb='widthChanged';function
    >>>>>> l(){return function(){}}
    >>>>>> 
    >>>>>>> On Dec 1, 2021, at 7:14 PM, Josh Tynjala <jo...@bowlerhat.dev> <ma...@bowlerhat.dev>
    >>>>>> wrote:
    >>>>>>>> I also noticed that none of these options seem to allow class names to
    >>>>>> be
    >>>>>>> dropped. That’s a lot of baggage being carried around for no apparent
    >>>>>>> reason.
    >>>>>>> 
    >>>>>>> It's certainly possible that I accidentally overlooked class renaming,
    >>>>>> but
    >>>>>>> that doesn't sound right to me. I'll double-check.
    > 



Re: Compiler options for reducing release build size of Royale projects (Part 2)

Posted by Harbs <ha...@gmail.com>.
source-map-explorer looks cool. Never tried it.

I’m not sure how useful that tool is for Royale other than seeing which classes were included. The issue here is cumulative size of the js files.

The saving for removing class names is a linear savings directly related to the number of classes you use.

I happen to know that the class names are only used by CSSSimpleStylesImpl in my app. That means the minified code which contains the class names is totally unnecessary if we can resolve the CSSSimpleStylesImpl lookup. To test how much of a difference it made, I deleted all the names from the minified code and gzipped the file. Just removing the class names resulted in about a 10KB reduction *after* gzipping for a 600KB+ gzipped js file. That’s about a 6% reduction for just the names. Not staggering, but significant.

Besides the size, it results in “cleaner” code, and the app structure is not obvious in the minified code. That’s a plus in my mind.

> On Dec 29, 2021, at 11:44 AM, Edward Stangler <es...@bradmark.com> wrote:
> 
> [I wrote this several weeks ago but didn't send it out.  The gist of it is that I don't think it's worth removing class names.]
> 
> 
> Which tools are you using to direct your investigation into reducing sizes?
> 
> 
> For your test case below:
> 
> 87,824 regular release mode
> 65,727 optimized (with your optimization switches)
> ------
> 22,097 bytes smaller (25% savings)
> (and SWF went up a few bytes)
> 
> < 3,600 bytes (5.5% of optimized size) is in full names at top
> 
> 
> For a basic Spark skin app (from issue #995):
> 
> 811,560 - regular release mode
> 631,789 - optimized (with your optimization switches)
> -------
> 179,771 bytes smaller (22% savings)
> 
> < 20,000 bytes (3% of optimized size) is in full names at top
> 
> For comparison, just the mentions of "declaredBy" (part of Reflection) take > 20,000 bytes (and that doesn't even include the other parts of the Reflection metadata, which are not used in that skin app).
> 
> 
> The source-map-explorer output for the Spark skin app looks like this:
> 
> 
> 
> (The one for your test case below--not shown--overemphasizes Language.js (~10KB), since the file sizes are so small (~60KB);  the one above is more representative of inefficiencies.)
> 
> 
> How will class names reduce the size significantly?
> 
> 
> 
> On 12/1/2021 12:15 PM, Harbs wrote:
>> I suspect that the following is happening:
>> 
>> 1. Language.as uses ROYALE_CLASS_INFO to find interfaces.
>> 2. That makes Closure Compiler assume ROYALE_CLASS_INFO is needed.
>> 3. All the info from ROYALE_CLASS_INFO including the class name and qname is preserved.
>> 
>> Perhaps we should have two variables:
>> 1. ROYALE_CLASS_INFO for the name and qname
>> 2. ROYALE_INTERFACE_INFO for the interface dependency
>> 
>> That should free up ROYALE_CLASS_INFO to be removed unless Reflection is used.
>> 
>> Thoughts?
>> 
>>> On Dec 1, 2021, at 7:50 PM, Harbs <ha...@gmail.com> <ma...@gmail.com> wrote:
>>> 
>>> It looks to me like that’s it.
>>> 
>>> We have this included in the minified code which should not be there:
>>> 
>>> ke.prototype.g={names:[{name:'IStyleObject',h:fb,kind:k}]};
>>> 
>>>> On Dec 1, 2021, at 7:46 PM, Harbs <ha...@gmail.com> <ma...@gmail.com> wrote:
>>>> 
>>>> Hmm. Maybe.
>>>> 
>>>> Greg, I think that’s your area of expertise.
>>>> 
>>>>> On Dec 1, 2021, at 7:45 PM, Josh Tynjala <jo...@bowlerhat.dev> <ma...@bowlerhat.dev> wrote:
>>>>> 
>>>>> Could those be the qname strings added to the ROYALE_CLASS_INFO object?
>>>>> 
>>>>> For example, I assume that this one:
>>>>> 
>>>>> fb='org.apache.royale.core.IStyleObject'
>>>>> 
>>>>> Comes from here:
>>>>> 
>>>>> /**
>>>>> * Metadata
>>>>> *
>>>>> * @type {Object.<string, Array.<Object>>}
>>>>> */
>>>>> org.apache.royale.core.IStyleObject.prototype.ROYALE_CLASS_INFO = { names:
>>>>> [{ name: 'IStyleObject', qName: 'org.apache.royale.core.IStyleObject',
>>>>> kind: 'interface' }] };
>>>>> 
>>>>> I'm not super familiar with the reflection system, so that's just a guess.
>>>>> 
>>>>> --
>>>>> Josh Tynjala
>>>>> Bowler Hat LLC <https://bowlerhat.dev> <https://bowlerhat.dev/>
>>>>> 
>>>>> 
>>>>> On Wed, Dec 1, 2021 at 9:25 AM Harbs <ha...@gmail.com> <ma...@gmail.com> wrote:
>>>>> 
>>>>>> Maybe I’m missing a compiler option, but I compiled this:
>>>>>> 
>>>>>> <?xml version="1.0" encoding="utf-8"?>
>>>>>> <js:Application xmlns:fx="http://ns.adobe.com/mxml/2009" <http://ns.adobe.com/mxml/2009>
>>>>>>              xmlns:js="library://ns.apache.org/royale/basic"
>>>>>>              applicationComplete="onComplete()">
>>>>>>  <fx:Script>
>>>>>>      <![CDATA[
>>>>>>          private function onComplete():void{
>>>>>>              trace("foo");
>>>>>>          }
>>>>>>      ]]>
>>>>>>  </fx:Script>
>>>>>>  <js:valuesImpl>
>>>>>>      <js:SimpleCSSValuesImpl />
>>>>>>  </js:valuesImpl>
>>>>>>  <js:initialView>
>>>>>>      <js:View>
>>>>>>          <js:Label text="ID" id="id1" localId="id1" />
>>>>>>      </js:View>
>>>>>>  </js:initialView>
>>>>>> </js:Application>
>>>>>> 
>>>>>> with this:
>>>>>> 
>>>>>> {
>>>>>>  "config": "royale",
>>>>>>  "compilerOptions": {
>>>>>>      "debug": true,
>>>>>>      "targets": ["JSRoyale"],
>>>>>>      "source-map": true,
>>>>>>      "remove-circulars": true
>>>>>>  },
>>>>>>  "additionalOptions": "-js-output-optimization=skipAsCoercions
>>>>>> -allow-abstract-classes=true -js-vector-emulation-class=Array
>>>>>> -js-vector-index-checks=false -js-complex-implicit-coercions=false
>>>>>> -export-public-symbols=false -prevent-rename-protected-symbols=false
>>>>>> -prevent-rename-public-static-methods=false
>>>>>> -prevent-rename-public-instance-methods=false
>>>>>> -prevent-rename-public-static-variables=false
>>>>>> -prevent-rename-public-instance-variables=false
>>>>>> -prevent-rename-public-instance-accessors=false",
>>>>>>  "files":
>>>>>>  [
>>>>>>      "src/test_project.mxml"
>>>>>>  ]
>>>>>> }
>>>>>> 
>>>>>> And got this at the top of the minified code:
>>>>>> 
>>>>>> 
>>>>>> var aa='Error #1034: Type Coercion failed: cannot convert
>>>>>> ',ba='applicationComplete',ca='array',da='backgroundImage',ea='border-box',fa='childrenAdded',f='class',ha='deferredSizeHandler',ia='explicitHeightChanged',ja='explicitWidthChanged',h='function',ka='handleInitComplete',la='handleSizeChange',ma='heightChanged',na='inherit',oa='initComplete',k='interface',pa='number',qa='object',ra='org.apache.royale.core.Application',sa='org.apache.royale.core.ApplicationBase',ta='org.apache.royale.core.Bead',
>>>>>> 
>>>>>> ua='org.apache.royale.core.BeadViewBase',va='org.apache.royale.core.DispatcherBead',wa='org.apache.royale.core.ElementWrapper',xa='org.apache.royale.core.GroupBase',ya='org.apache.royale.core.HTMLElementWrapper',za='org.apache.royale.core.IApplicationView',Aa='org.apache.royale.core.IBead',Ba='org.apache.royale.core.IBeadController',Ca='org.apache.royale.core.IBeadLayout',Da='org.apache.royale.core.IBeadModel',Ea='org.apache.royale.core.IBeadView',Fa='org.apache.royale.core.IBorderPaddingMarginValuesImpl',
>>>>>> 
>>>>>> Ga='org.apache.royale.core.ICSSImpl',Ha='org.apache.royale.core.IChild',Ia='org.apache.royale.core.IContainer',Ja='org.apache.royale.core.IContentViewHost',Ka='org.apache.royale.core.IDocument',La='org.apache.royale.core.IFlexInfo',Ma='org.apache.royale.core.IId',Na='org.apache.royale.core.IInitialViewApplication',Oa='org.apache.royale.core.ILayoutChild',Pa='org.apache.royale.core.ILayoutHost',Qa='org.apache.royale.core.ILayoutParent',Ra='org.apache.royale.core.ILayoutView',Sa='org.apache.royale.core.IMXMLDocument',
>>>>>> 
>>>>>> Ta='org.apache.royale.core.IMeasurementBead',Ua='org.apache.royale.core.IParent',Va='org.apache.royale.core.IParentIUIBase',Wa='org.apache.royale.core.IPopUpHost',Xa='org.apache.royale.core.IPopUpHostParent',Ya='org.apache.royale.core.IRenderedObject',Za='org.apache.royale.core.IRoyaleElement',$a='org.apache.royale.core.IState',ab='org.apache.royale.core.IStatesImpl',bb='org.apache.royale.core.IStatesObject',cb='org.apache.royale.core.IStrand',db='org.apache.royale.core.IStrandWithModel',eb='org.apache.royale.core.IStrandWithModelView',
>>>>>> 
>>>>>> fb='org.apache.royale.core.IStyleObject',gb='org.apache.royale.core.IStyleableObject',hb='org.apache.royale.core.IUIBase',ib='org.apache.royale.core.IValuesImpl',jb='org.apache.royale.core.LayoutBase',kb='org.apache.royale.core.SimpleCSSValuesImpl',lb='org.apache.royale.core.UIBase',mb='org.apache.royale.core.ValuesManager',nb='org.apache.royale.core.View',ob='org.apache.royale.core.ViewBase',pb='org.apache.royale.core.WrappedHTMLElement',qb='org.apache.royale.core.layout.EdgeData',rb='org.apache.royale.core.layout.LayoutData',
>>>>>> 
>>>>>> sb='org.apache.royale.core.layout.MarginData',tb='org.apache.royale.core.styles.BorderStyles',ub='org.apache.royale.events.BrowserEvent',vb='org.apache.royale.events.ElementEvents',wb='org.apache.royale.events.Event',xb='org.apache.royale.events.EventDispatcher',yb='org.apache.royale.events.IBrowserEvent',zb='org.apache.royale.events.IEventDispatcher',Ab='org.apache.royale.events.IRoyaleEvent',Bb='org.apache.royale.events.ValueChangeEvent',Cb='org.apache.royale.events.ValueEvent',Db='org.apache.royale.events.utils.EventUtils',
>>>>>> Eb='org.apache.royale.html.Label',Fb='org.apache.royale.html.beads.GroupView',Gb='org.apache.royale.html.beads.layouts.BasicLayout',Hb='org.apache.royale.utils.CSSUtils',Ib='org.apache.royale.utils.MXMLDataInterpreter',Jb='org.apache.royale.utils.StringPadder',Kb='org.apache.royale.utils.Timer',Lb='percentHeightChanged',Mb='percentWidthChanged',Nb='resizeHandler',Ob='sizeChanged',Pb='string',Qb='test_project',Rb='viewChanged',Sb='widthChanged';function
>>>>>> l(){return function(){}}
>>>>>> 
>>>>>>> On Dec 1, 2021, at 7:14 PM, Josh Tynjala <jo...@bowlerhat.dev> <ma...@bowlerhat.dev>
>>>>>> wrote:
>>>>>>>> I also noticed that none of these options seem to allow class names to
>>>>>> be
>>>>>>> dropped. That’s a lot of baggage being carried around for no apparent
>>>>>>> reason.
>>>>>>> 
>>>>>>> It's certainly possible that I accidentally overlooked class renaming,
>>>>>> but
>>>>>>> that doesn't sound right to me. I'll double-check.
> 


Re: Compiler options for reducing release build size of Royale projects (Part 2)

Posted by Edward Stangler <es...@bradmark.com>.
[I wrote this several weeks ago but didn't send it out.  The gist of it is that I don't think it's worth removing class names.]


Which tools are you using to direct your investigation into reducing sizes?


For your test case below:

87,824 regular release mode
65,727 optimized (with your optimization switches)
------
22,097 bytes smaller (25% savings)
(and SWF went up a few bytes)

< 3,600 bytes (5.5% of optimized size) is in full names at top


For a basic Spark skin app (from issue #995):

811,560 - regular release mode
631,789 - optimized (with your optimization switches)
-------
179,771 bytes smaller (22% savings)

< 20,000 bytes (3% of optimized size) is in full names at top

For comparison, just the mentions of "declaredBy" (part of Reflection) take > 20,000 bytes (and that doesn't even include the other parts of the Reflection metadata, which are not used in that skin app).


The source-map-explorer output for the Spark skin app looks like this:

[cid:part1.165CDA6B.6BB0CFF0@bradmark.com]

(The one for your test case below--not shown--overemphasizes Language.js (~10KB), since the file sizes are so small (~60KB);  the one above is more representative of inefficiencies.)


How will class names reduce the size significantly?



On 12/1/2021 12:15 PM, Harbs wrote:

I suspect that the following is happening:

1. Language.as uses ROYALE_CLASS_INFO to find interfaces.
2. That makes Closure Compiler assume ROYALE_CLASS_INFO is needed.
3. All the info from ROYALE_CLASS_INFO including the class name and qname is preserved.

Perhaps we should have two variables:
1. ROYALE_CLASS_INFO for the name and qname
2. ROYALE_INTERFACE_INFO for the interface dependency

That should free up ROYALE_CLASS_INFO to be removed unless Reflection is used.

Thoughts?



On Dec 1, 2021, at 7:50 PM, Harbs <ha...@gmail.com> wrote:

It looks to me like that’s it.

We have this included in the minified code which should not be there:

ke.prototype.g={names:[{name:'IStyleObject',h:fb,kind:k}]};



On Dec 1, 2021, at 7:46 PM, Harbs <ha...@gmail.com> wrote:

Hmm. Maybe.

Greg, I think that’s your area of expertise.



On Dec 1, 2021, at 7:45 PM, Josh Tynjala <jo...@bowlerhat.dev> wrote:

Could those be the qname strings added to the ROYALE_CLASS_INFO object?

For example, I assume that this one:

fb='org.apache.royale.core.IStyleObject'

Comes from here:

/**
* Metadata
*
* @type {Object.<string, Array.<Object>>}
*/
org.apache.royale.core.IStyleObject.prototype.ROYALE_CLASS_INFO = { names:
[{ name: 'IStyleObject', qName: 'org.apache.royale.core.IStyleObject',
kind: 'interface' }] };

I'm not super familiar with the reflection system, so that's just a guess.

--
Josh Tynjala
Bowler Hat LLC <https://bowlerhat.dev><https://bowlerhat.dev>


On Wed, Dec 1, 2021 at 9:25 AM Harbs <ha...@gmail.com> wrote:



Maybe I’m missing a compiler option, but I compiled this:

<?xml version="1.0" encoding="utf-8"?>
<js:Application xmlns:fx="http://ns.adobe.com/mxml/2009"<http://ns.adobe.com/mxml/2009>
             xmlns:js="library://ns.apache.org/royale/basic"
             applicationComplete="onComplete()">
 <fx:Script>
     <![CDATA[
         private function onComplete():void{
             trace("foo");
         }
     ]]>
 </fx:Script>
 <js:valuesImpl>
     <js:SimpleCSSValuesImpl />
 </js:valuesImpl>
 <js:initialView>
     <js:View>
         <js:Label text="ID" id="id1" localId="id1" />
     </js:View>
 </js:initialView>
</js:Application>

with this:

{
 "config": "royale",
 "compilerOptions": {
     "debug": true,
     "targets": ["JSRoyale"],
     "source-map": true,
     "remove-circulars": true
 },
 "additionalOptions": "-js-output-optimization=skipAsCoercions
-allow-abstract-classes=true -js-vector-emulation-class=Array
-js-vector-index-checks=false -js-complex-implicit-coercions=false
-export-public-symbols=false -prevent-rename-protected-symbols=false
-prevent-rename-public-static-methods=false
-prevent-rename-public-instance-methods=false
-prevent-rename-public-static-variables=false
-prevent-rename-public-instance-variables=false
-prevent-rename-public-instance-accessors=false",
 "files":
 [
     "src/test_project.mxml"
 ]
}

And got this at the top of the minified code:


var aa='Error #1034: Type Coercion failed: cannot convert
',ba='applicationComplete',ca='array',da='backgroundImage',ea='border-box',fa='childrenAdded',f='class',ha='deferredSizeHandler',ia='explicitHeightChanged',ja='explicitWidthChanged',h='function',ka='handleInitComplete',la='handleSizeChange',ma='heightChanged',na='inherit',oa='initComplete',k='interface',pa='number',qa='object',ra='org.apache.royale.core.Application',sa='org.apache.royale.core.ApplicationBase',ta='org.apache.royale.core.Bead',

ua='org.apache.royale.core.BeadViewBase',va='org.apache.royale.core.DispatcherBead',wa='org.apache.royale.core.ElementWrapper',xa='org.apache.royale.core.GroupBase',ya='org.apache.royale.core.HTMLElementWrapper',za='org.apache.royale.core.IApplicationView',Aa='org.apache.royale.core.IBead',Ba='org.apache.royale.core.IBeadController',Ca='org.apache.royale.core.IBeadLayout',Da='org.apache.royale.core.IBeadModel',Ea='org.apache.royale.core.IBeadView',Fa='org.apache.royale.core.IBorderPaddingMarginValuesImpl',

Ga='org.apache.royale.core.ICSSImpl',Ha='org.apache.royale.core.IChild',Ia='org.apache.royale.core.IContainer',Ja='org.apache.royale.core.IContentViewHost',Ka='org.apache.royale.core.IDocument',La='org.apache.royale.core.IFlexInfo',Ma='org.apache.royale.core.IId',Na='org.apache.royale.core.IInitialViewApplication',Oa='org.apache.royale.core.ILayoutChild',Pa='org.apache.royale.core.ILayoutHost',Qa='org.apache.royale.core.ILayoutParent',Ra='org.apache.royale.core.ILayoutView',Sa='org.apache.royale.core.IMXMLDocument',

Ta='org.apache.royale.core.IMeasurementBead',Ua='org.apache.royale.core.IParent',Va='org.apache.royale.core.IParentIUIBase',Wa='org.apache.royale.core.IPopUpHost',Xa='org.apache.royale.core.IPopUpHostParent',Ya='org.apache.royale.core.IRenderedObject',Za='org.apache.royale.core.IRoyaleElement',$a='org.apache.royale.core.IState',ab='org.apache.royale.core.IStatesImpl',bb='org.apache.royale.core.IStatesObject',cb='org.apache.royale.core.IStrand',db='org.apache.royale.core.IStrandWithModel',eb='org.apache.royale.core.IStrandWithModelView',

fb='org.apache.royale.core.IStyleObject',gb='org.apache.royale.core.IStyleableObject',hb='org.apache.royale.core.IUIBase',ib='org.apache.royale.core.IValuesImpl',jb='org.apache.royale.core.LayoutBase',kb='org.apache.royale.core.SimpleCSSValuesImpl',lb='org.apache.royale.core.UIBase',mb='org.apache.royale.core.ValuesManager',nb='org.apache.royale.core.View',ob='org.apache.royale.core.ViewBase',pb='org.apache.royale.core.WrappedHTMLElement',qb='org.apache.royale.core.layout.EdgeData',rb='org.apache.royale.core.layout.LayoutData',

sb='org.apache.royale.core.layout.MarginData',tb='org.apache.royale.core.styles.BorderStyles',ub='org.apache.royale.events.BrowserEvent',vb='org.apache.royale.events.ElementEvents',wb='org.apache.royale.events.Event',xb='org.apache.royale.events.EventDispatcher',yb='org.apache.royale.events.IBrowserEvent',zb='org.apache.royale.events.IEventDispatcher',Ab='org.apache.royale.events.IRoyaleEvent',Bb='org.apache.royale.events.ValueChangeEvent',Cb='org.apache.royale.events.ValueEvent',Db='org.apache.royale.events.utils.EventUtils',
Eb='org.apache.royale.html.Label',Fb='org.apache.royale.html.beads.GroupView',Gb='org.apache.royale.html.beads.layouts.BasicLayout',Hb='org.apache.royale.utils.CSSUtils',Ib='org.apache.royale.utils.MXMLDataInterpreter',Jb='org.apache.royale.utils.StringPadder',Kb='org.apache.royale.utils.Timer',Lb='percentHeightChanged',Mb='percentWidthChanged',Nb='resizeHandler',Ob='sizeChanged',Pb='string',Qb='test_project',Rb='viewChanged',Sb='widthChanged';function
l(){return function(){}}



On Dec 1, 2021, at 7:14 PM, Josh Tynjala <jo...@bowlerhat.dev>


wrote:


I also noticed that none of these options seem to allow class names to


be


dropped. That’s a lot of baggage being carried around for no apparent
reason.

It's certainly possible that I accidentally overlooked class renaming,


but


that doesn't sound right to me. I'll double-check.



Re: Compiler options for reducing release build size of Royale projects (Part 2)

Posted by Harbs <ha...@gmail.com>.
I summarized this in an issue: https://github.com/apache/royale-compiler/issues/202

> On Dec 1, 2021, at 8:13 PM, Harbs <ha...@gmail.com> wrote:
> 
> I suspect that the following is happening:
> 
> 1. Language.as uses ROYALE_CLASS_INFO to find interfaces.
> 2. That makes Closure Compiler assume ROYALE_CLASS_INFO is needed.
> 3. All the info from ROYALE_CLASS_INFO including the class name and qname is preserved.
> 
> Perhaps we should have two variables:
> 1. ROYALE_CLASS_INFO for the name and qname
> 2. ROYALE_INTERFACE_INFO for the interface dependency
> 
> That should free up ROYALE_CLASS_INFO to be removed unless Reflection is used.
> 
> Thoughts?
> 
>> On Dec 1, 2021, at 7:50 PM, Harbs <ha...@gmail.com> wrote:
>> 
>> It looks to me like that’s it.
>> 
>> We have this included in the minified code which should not be there:
>> 
>> ke.prototype.g={names:[{name:'IStyleObject',h:fb,kind:k}]};
>> 
>>> On Dec 1, 2021, at 7:46 PM, Harbs <ha...@gmail.com> wrote:
>>> 
>>> Hmm. Maybe.
>>> 
>>> Greg, I think that’s your area of expertise.
>>> 
>>>> On Dec 1, 2021, at 7:45 PM, Josh Tynjala <jo...@bowlerhat.dev> wrote:
>>>> 
>>>> Could those be the qname strings added to the ROYALE_CLASS_INFO object?
>>>> 
>>>> For example, I assume that this one:
>>>> 
>>>> fb='org.apache.royale.core.IStyleObject'
>>>> 
>>>> Comes from here:
>>>> 
>>>> /**
>>>> * Metadata
>>>> *
>>>> * @type {Object.<string, Array.<Object>>}
>>>> */
>>>> org.apache.royale.core.IStyleObject.prototype.ROYALE_CLASS_INFO = { names:
>>>> [{ name: 'IStyleObject', qName: 'org.apache.royale.core.IStyleObject',
>>>> kind: 'interface' }] };
>>>> 
>>>> I'm not super familiar with the reflection system, so that's just a guess.
>>>> 
>>>> --
>>>> Josh Tynjala
>>>> Bowler Hat LLC <https://bowlerhat.dev>
>>>> 
>>>> 
>>>> On Wed, Dec 1, 2021 at 9:25 AM Harbs <ha...@gmail.com> wrote:
>>>> 
>>>>> Maybe I’m missing a compiler option, but I compiled this:
>>>>> 
>>>>> <?xml version="1.0" encoding="utf-8"?>
>>>>> <js:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
>>>>>             xmlns:js="library://ns.apache.org/royale/basic"
>>>>>             applicationComplete="onComplete()">
>>>>> <fx:Script>
>>>>>     <![CDATA[
>>>>>         private function onComplete():void{
>>>>>             trace("foo");
>>>>>         }
>>>>>     ]]>
>>>>> </fx:Script>
>>>>> <js:valuesImpl>
>>>>>     <js:SimpleCSSValuesImpl />
>>>>> </js:valuesImpl>
>>>>> <js:initialView>
>>>>>     <js:View>
>>>>>         <js:Label text="ID" id="id1" localId="id1" />
>>>>>     </js:View>
>>>>> </js:initialView>
>>>>> </js:Application>
>>>>> 
>>>>> with this:
>>>>> 
>>>>> {
>>>>> "config": "royale",
>>>>> "compilerOptions": {
>>>>>     "debug": true,
>>>>>     "targets": ["JSRoyale"],
>>>>>     "source-map": true,
>>>>>     "remove-circulars": true
>>>>> },
>>>>> "additionalOptions": "-js-output-optimization=skipAsCoercions
>>>>> -allow-abstract-classes=true -js-vector-emulation-class=Array
>>>>> -js-vector-index-checks=false -js-complex-implicit-coercions=false
>>>>> -export-public-symbols=false -prevent-rename-protected-symbols=false
>>>>> -prevent-rename-public-static-methods=false
>>>>> -prevent-rename-public-instance-methods=false
>>>>> -prevent-rename-public-static-variables=false
>>>>> -prevent-rename-public-instance-variables=false
>>>>> -prevent-rename-public-instance-accessors=false",
>>>>> "files":
>>>>> [
>>>>>     "src/test_project.mxml"
>>>>> ]
>>>>> }
>>>>> 
>>>>> And got this at the top of the minified code:
>>>>> 
>>>>> 
>>>>> var aa='Error #1034: Type Coercion failed: cannot convert
>>>>> ',ba='applicationComplete',ca='array',da='backgroundImage',ea='border-box',fa='childrenAdded',f='class',ha='deferredSizeHandler',ia='explicitHeightChanged',ja='explicitWidthChanged',h='function',ka='handleInitComplete',la='handleSizeChange',ma='heightChanged',na='inherit',oa='initComplete',k='interface',pa='number',qa='object',ra='org.apache.royale.core.Application',sa='org.apache.royale.core.ApplicationBase',ta='org.apache.royale.core.Bead',
>>>>> 
>>>>> ua='org.apache.royale.core.BeadViewBase',va='org.apache.royale.core.DispatcherBead',wa='org.apache.royale.core.ElementWrapper',xa='org.apache.royale.core.GroupBase',ya='org.apache.royale.core.HTMLElementWrapper',za='org.apache.royale.core.IApplicationView',Aa='org.apache.royale.core.IBead',Ba='org.apache.royale.core.IBeadController',Ca='org.apache.royale.core.IBeadLayout',Da='org.apache.royale.core.IBeadModel',Ea='org.apache.royale.core.IBeadView',Fa='org.apache.royale.core.IBorderPaddingMarginValuesImpl',
>>>>> 
>>>>> Ga='org.apache.royale.core.ICSSImpl',Ha='org.apache.royale.core.IChild',Ia='org.apache.royale.core.IContainer',Ja='org.apache.royale.core.IContentViewHost',Ka='org.apache.royale.core.IDocument',La='org.apache.royale.core.IFlexInfo',Ma='org.apache.royale.core.IId',Na='org.apache.royale.core.IInitialViewApplication',Oa='org.apache.royale.core.ILayoutChild',Pa='org.apache.royale.core.ILayoutHost',Qa='org.apache.royale.core.ILayoutParent',Ra='org.apache.royale.core.ILayoutView',Sa='org.apache.royale.core.IMXMLDocument',
>>>>> 
>>>>> Ta='org.apache.royale.core.IMeasurementBead',Ua='org.apache.royale.core.IParent',Va='org.apache.royale.core.IParentIUIBase',Wa='org.apache.royale.core.IPopUpHost',Xa='org.apache.royale.core.IPopUpHostParent',Ya='org.apache.royale.core.IRenderedObject',Za='org.apache.royale.core.IRoyaleElement',$a='org.apache.royale.core.IState',ab='org.apache.royale.core.IStatesImpl',bb='org.apache.royale.core.IStatesObject',cb='org.apache.royale.core.IStrand',db='org.apache.royale.core.IStrandWithModel',eb='org.apache.royale.core.IStrandWithModelView',
>>>>> 
>>>>> fb='org.apache.royale.core.IStyleObject',gb='org.apache.royale.core.IStyleableObject',hb='org.apache.royale.core.IUIBase',ib='org.apache.royale.core.IValuesImpl',jb='org.apache.royale.core.LayoutBase',kb='org.apache.royale.core.SimpleCSSValuesImpl',lb='org.apache.royale.core.UIBase',mb='org.apache.royale.core.ValuesManager',nb='org.apache.royale.core.View',ob='org.apache.royale.core.ViewBase',pb='org.apache.royale.core.WrappedHTMLElement',qb='org.apache.royale.core.layout.EdgeData',rb='org.apache.royale.core.layout.LayoutData',
>>>>> 
>>>>> sb='org.apache.royale.core.layout.MarginData',tb='org.apache.royale.core.styles.BorderStyles',ub='org.apache.royale.events.BrowserEvent',vb='org.apache.royale.events.ElementEvents',wb='org.apache.royale.events.Event',xb='org.apache.royale.events.EventDispatcher',yb='org.apache.royale.events.IBrowserEvent',zb='org.apache.royale.events.IEventDispatcher',Ab='org.apache.royale.events.IRoyaleEvent',Bb='org.apache.royale.events.ValueChangeEvent',Cb='org.apache.royale.events.ValueEvent',Db='org.apache.royale.events.utils.EventUtils',
>>>>> Eb='org.apache.royale.html.Label',Fb='org.apache.royale.html.beads.GroupView',Gb='org.apache.royale.html.beads.layouts.BasicLayout',Hb='org.apache.royale.utils.CSSUtils',Ib='org.apache.royale.utils.MXMLDataInterpreter',Jb='org.apache.royale.utils.StringPadder',Kb='org.apache.royale.utils.Timer',Lb='percentHeightChanged',Mb='percentWidthChanged',Nb='resizeHandler',Ob='sizeChanged',Pb='string',Qb='test_project',Rb='viewChanged',Sb='widthChanged';function
>>>>> l(){return function(){}}
>>>>> 
>>>>>> On Dec 1, 2021, at 7:14 PM, Josh Tynjala <jo...@bowlerhat.dev>
>>>>> wrote:
>>>>>> 
>>>>>>> I also noticed that none of these options seem to allow class names to
>>>>> be
>>>>>> dropped. That’s a lot of baggage being carried around for no apparent
>>>>>> reason.
>>>>>> 
>>>>>> It's certainly possible that I accidentally overlooked class renaming,
>>>>> but
>>>>>> that doesn't sound right to me. I'll double-check.
>>>>> 
>>>>> 
>>> 
>> 
> 


Re: Compiler options for reducing release build size of Royale projects (Part 2)

Posted by Harbs <ha...@gmail.com>.
I suspect that the following is happening:

1. Language.as uses ROYALE_CLASS_INFO to find interfaces.
2. That makes Closure Compiler assume ROYALE_CLASS_INFO is needed.
3. All the info from ROYALE_CLASS_INFO including the class name and qname is preserved.

Perhaps we should have two variables:
1. ROYALE_CLASS_INFO for the name and qname
2. ROYALE_INTERFACE_INFO for the interface dependency

That should free up ROYALE_CLASS_INFO to be removed unless Reflection is used.

Thoughts?

> On Dec 1, 2021, at 7:50 PM, Harbs <ha...@gmail.com> wrote:
> 
> It looks to me like that’s it.
> 
> We have this included in the minified code which should not be there:
> 
> ke.prototype.g={names:[{name:'IStyleObject',h:fb,kind:k}]};
> 
>> On Dec 1, 2021, at 7:46 PM, Harbs <ha...@gmail.com> wrote:
>> 
>> Hmm. Maybe.
>> 
>> Greg, I think that’s your area of expertise.
>> 
>>> On Dec 1, 2021, at 7:45 PM, Josh Tynjala <jo...@bowlerhat.dev> wrote:
>>> 
>>> Could those be the qname strings added to the ROYALE_CLASS_INFO object?
>>> 
>>> For example, I assume that this one:
>>> 
>>> fb='org.apache.royale.core.IStyleObject'
>>> 
>>> Comes from here:
>>> 
>>> /**
>>> * Metadata
>>> *
>>> * @type {Object.<string, Array.<Object>>}
>>> */
>>> org.apache.royale.core.IStyleObject.prototype.ROYALE_CLASS_INFO = { names:
>>> [{ name: 'IStyleObject', qName: 'org.apache.royale.core.IStyleObject',
>>> kind: 'interface' }] };
>>> 
>>> I'm not super familiar with the reflection system, so that's just a guess.
>>> 
>>> --
>>> Josh Tynjala
>>> Bowler Hat LLC <https://bowlerhat.dev>
>>> 
>>> 
>>> On Wed, Dec 1, 2021 at 9:25 AM Harbs <ha...@gmail.com> wrote:
>>> 
>>>> Maybe I’m missing a compiler option, but I compiled this:
>>>> 
>>>> <?xml version="1.0" encoding="utf-8"?>
>>>> <js:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
>>>>              xmlns:js="library://ns.apache.org/royale/basic"
>>>>              applicationComplete="onComplete()">
>>>>  <fx:Script>
>>>>      <![CDATA[
>>>>          private function onComplete():void{
>>>>              trace("foo");
>>>>          }
>>>>      ]]>
>>>>  </fx:Script>
>>>>  <js:valuesImpl>
>>>>      <js:SimpleCSSValuesImpl />
>>>>  </js:valuesImpl>
>>>>  <js:initialView>
>>>>      <js:View>
>>>>          <js:Label text="ID" id="id1" localId="id1" />
>>>>      </js:View>
>>>>  </js:initialView>
>>>> </js:Application>
>>>> 
>>>> with this:
>>>> 
>>>> {
>>>>  "config": "royale",
>>>>  "compilerOptions": {
>>>>      "debug": true,
>>>>      "targets": ["JSRoyale"],
>>>>      "source-map": true,
>>>>      "remove-circulars": true
>>>>  },
>>>>  "additionalOptions": "-js-output-optimization=skipAsCoercions
>>>> -allow-abstract-classes=true -js-vector-emulation-class=Array
>>>> -js-vector-index-checks=false -js-complex-implicit-coercions=false
>>>> -export-public-symbols=false -prevent-rename-protected-symbols=false
>>>> -prevent-rename-public-static-methods=false
>>>> -prevent-rename-public-instance-methods=false
>>>> -prevent-rename-public-static-variables=false
>>>> -prevent-rename-public-instance-variables=false
>>>> -prevent-rename-public-instance-accessors=false",
>>>>  "files":
>>>>  [
>>>>      "src/test_project.mxml"
>>>>  ]
>>>> }
>>>> 
>>>> And got this at the top of the minified code:
>>>> 
>>>> 
>>>> var aa='Error #1034: Type Coercion failed: cannot convert
>>>> ',ba='applicationComplete',ca='array',da='backgroundImage',ea='border-box',fa='childrenAdded',f='class',ha='deferredSizeHandler',ia='explicitHeightChanged',ja='explicitWidthChanged',h='function',ka='handleInitComplete',la='handleSizeChange',ma='heightChanged',na='inherit',oa='initComplete',k='interface',pa='number',qa='object',ra='org.apache.royale.core.Application',sa='org.apache.royale.core.ApplicationBase',ta='org.apache.royale.core.Bead',
>>>> 
>>>> ua='org.apache.royale.core.BeadViewBase',va='org.apache.royale.core.DispatcherBead',wa='org.apache.royale.core.ElementWrapper',xa='org.apache.royale.core.GroupBase',ya='org.apache.royale.core.HTMLElementWrapper',za='org.apache.royale.core.IApplicationView',Aa='org.apache.royale.core.IBead',Ba='org.apache.royale.core.IBeadController',Ca='org.apache.royale.core.IBeadLayout',Da='org.apache.royale.core.IBeadModel',Ea='org.apache.royale.core.IBeadView',Fa='org.apache.royale.core.IBorderPaddingMarginValuesImpl',
>>>> 
>>>> Ga='org.apache.royale.core.ICSSImpl',Ha='org.apache.royale.core.IChild',Ia='org.apache.royale.core.IContainer',Ja='org.apache.royale.core.IContentViewHost',Ka='org.apache.royale.core.IDocument',La='org.apache.royale.core.IFlexInfo',Ma='org.apache.royale.core.IId',Na='org.apache.royale.core.IInitialViewApplication',Oa='org.apache.royale.core.ILayoutChild',Pa='org.apache.royale.core.ILayoutHost',Qa='org.apache.royale.core.ILayoutParent',Ra='org.apache.royale.core.ILayoutView',Sa='org.apache.royale.core.IMXMLDocument',
>>>> 
>>>> Ta='org.apache.royale.core.IMeasurementBead',Ua='org.apache.royale.core.IParent',Va='org.apache.royale.core.IParentIUIBase',Wa='org.apache.royale.core.IPopUpHost',Xa='org.apache.royale.core.IPopUpHostParent',Ya='org.apache.royale.core.IRenderedObject',Za='org.apache.royale.core.IRoyaleElement',$a='org.apache.royale.core.IState',ab='org.apache.royale.core.IStatesImpl',bb='org.apache.royale.core.IStatesObject',cb='org.apache.royale.core.IStrand',db='org.apache.royale.core.IStrandWithModel',eb='org.apache.royale.core.IStrandWithModelView',
>>>> 
>>>> fb='org.apache.royale.core.IStyleObject',gb='org.apache.royale.core.IStyleableObject',hb='org.apache.royale.core.IUIBase',ib='org.apache.royale.core.IValuesImpl',jb='org.apache.royale.core.LayoutBase',kb='org.apache.royale.core.SimpleCSSValuesImpl',lb='org.apache.royale.core.UIBase',mb='org.apache.royale.core.ValuesManager',nb='org.apache.royale.core.View',ob='org.apache.royale.core.ViewBase',pb='org.apache.royale.core.WrappedHTMLElement',qb='org.apache.royale.core.layout.EdgeData',rb='org.apache.royale.core.layout.LayoutData',
>>>> 
>>>> sb='org.apache.royale.core.layout.MarginData',tb='org.apache.royale.core.styles.BorderStyles',ub='org.apache.royale.events.BrowserEvent',vb='org.apache.royale.events.ElementEvents',wb='org.apache.royale.events.Event',xb='org.apache.royale.events.EventDispatcher',yb='org.apache.royale.events.IBrowserEvent',zb='org.apache.royale.events.IEventDispatcher',Ab='org.apache.royale.events.IRoyaleEvent',Bb='org.apache.royale.events.ValueChangeEvent',Cb='org.apache.royale.events.ValueEvent',Db='org.apache.royale.events.utils.EventUtils',
>>>> Eb='org.apache.royale.html.Label',Fb='org.apache.royale.html.beads.GroupView',Gb='org.apache.royale.html.beads.layouts.BasicLayout',Hb='org.apache.royale.utils.CSSUtils',Ib='org.apache.royale.utils.MXMLDataInterpreter',Jb='org.apache.royale.utils.StringPadder',Kb='org.apache.royale.utils.Timer',Lb='percentHeightChanged',Mb='percentWidthChanged',Nb='resizeHandler',Ob='sizeChanged',Pb='string',Qb='test_project',Rb='viewChanged',Sb='widthChanged';function
>>>> l(){return function(){}}
>>>> 
>>>>> On Dec 1, 2021, at 7:14 PM, Josh Tynjala <jo...@bowlerhat.dev>
>>>> wrote:
>>>>> 
>>>>>> I also noticed that none of these options seem to allow class names to
>>>> be
>>>>> dropped. That’s a lot of baggage being carried around for no apparent
>>>>> reason.
>>>>> 
>>>>> It's certainly possible that I accidentally overlooked class renaming,
>>>> but
>>>>> that doesn't sound right to me. I'll double-check.
>>>> 
>>>> 
>> 
> 


Re: Compiler options for reducing release build size of Royale projects (Part 2)

Posted by Harbs <ha...@gmail.com>.
It looks to me like that’s it.

We have this included in the minified code which should not be there:

ke.prototype.g={names:[{name:'IStyleObject',h:fb,kind:k}]};

> On Dec 1, 2021, at 7:46 PM, Harbs <ha...@gmail.com> wrote:
> 
> Hmm. Maybe.
> 
> Greg, I think that’s your area of expertise.
> 
>> On Dec 1, 2021, at 7:45 PM, Josh Tynjala <jo...@bowlerhat.dev> wrote:
>> 
>> Could those be the qname strings added to the ROYALE_CLASS_INFO object?
>> 
>> For example, I assume that this one:
>> 
>> fb='org.apache.royale.core.IStyleObject'
>> 
>> Comes from here:
>> 
>> /**
>> * Metadata
>> *
>> * @type {Object.<string, Array.<Object>>}
>> */
>> org.apache.royale.core.IStyleObject.prototype.ROYALE_CLASS_INFO = { names:
>> [{ name: 'IStyleObject', qName: 'org.apache.royale.core.IStyleObject',
>> kind: 'interface' }] };
>> 
>> I'm not super familiar with the reflection system, so that's just a guess.
>> 
>> --
>> Josh Tynjala
>> Bowler Hat LLC <https://bowlerhat.dev>
>> 
>> 
>> On Wed, Dec 1, 2021 at 9:25 AM Harbs <ha...@gmail.com> wrote:
>> 
>>> Maybe I’m missing a compiler option, but I compiled this:
>>> 
>>> <?xml version="1.0" encoding="utf-8"?>
>>> <js:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
>>>               xmlns:js="library://ns.apache.org/royale/basic"
>>>               applicationComplete="onComplete()">
>>>   <fx:Script>
>>>       <![CDATA[
>>>           private function onComplete():void{
>>>               trace("foo");
>>>           }
>>>       ]]>
>>>   </fx:Script>
>>>   <js:valuesImpl>
>>>       <js:SimpleCSSValuesImpl />
>>>   </js:valuesImpl>
>>>   <js:initialView>
>>>       <js:View>
>>>           <js:Label text="ID" id="id1" localId="id1" />
>>>       </js:View>
>>>   </js:initialView>
>>> </js:Application>
>>> 
>>> with this:
>>> 
>>> {
>>>   "config": "royale",
>>>   "compilerOptions": {
>>>       "debug": true,
>>>       "targets": ["JSRoyale"],
>>>       "source-map": true,
>>>       "remove-circulars": true
>>>   },
>>>   "additionalOptions": "-js-output-optimization=skipAsCoercions
>>> -allow-abstract-classes=true -js-vector-emulation-class=Array
>>> -js-vector-index-checks=false -js-complex-implicit-coercions=false
>>> -export-public-symbols=false -prevent-rename-protected-symbols=false
>>> -prevent-rename-public-static-methods=false
>>> -prevent-rename-public-instance-methods=false
>>> -prevent-rename-public-static-variables=false
>>> -prevent-rename-public-instance-variables=false
>>> -prevent-rename-public-instance-accessors=false",
>>>   "files":
>>>   [
>>>       "src/test_project.mxml"
>>>   ]
>>> }
>>> 
>>> And got this at the top of the minified code:
>>> 
>>> 
>>> var aa='Error #1034: Type Coercion failed: cannot convert
>>> ',ba='applicationComplete',ca='array',da='backgroundImage',ea='border-box',fa='childrenAdded',f='class',ha='deferredSizeHandler',ia='explicitHeightChanged',ja='explicitWidthChanged',h='function',ka='handleInitComplete',la='handleSizeChange',ma='heightChanged',na='inherit',oa='initComplete',k='interface',pa='number',qa='object',ra='org.apache.royale.core.Application',sa='org.apache.royale.core.ApplicationBase',ta='org.apache.royale.core.Bead',
>>> 
>>> ua='org.apache.royale.core.BeadViewBase',va='org.apache.royale.core.DispatcherBead',wa='org.apache.royale.core.ElementWrapper',xa='org.apache.royale.core.GroupBase',ya='org.apache.royale.core.HTMLElementWrapper',za='org.apache.royale.core.IApplicationView',Aa='org.apache.royale.core.IBead',Ba='org.apache.royale.core.IBeadController',Ca='org.apache.royale.core.IBeadLayout',Da='org.apache.royale.core.IBeadModel',Ea='org.apache.royale.core.IBeadView',Fa='org.apache.royale.core.IBorderPaddingMarginValuesImpl',
>>> 
>>> Ga='org.apache.royale.core.ICSSImpl',Ha='org.apache.royale.core.IChild',Ia='org.apache.royale.core.IContainer',Ja='org.apache.royale.core.IContentViewHost',Ka='org.apache.royale.core.IDocument',La='org.apache.royale.core.IFlexInfo',Ma='org.apache.royale.core.IId',Na='org.apache.royale.core.IInitialViewApplication',Oa='org.apache.royale.core.ILayoutChild',Pa='org.apache.royale.core.ILayoutHost',Qa='org.apache.royale.core.ILayoutParent',Ra='org.apache.royale.core.ILayoutView',Sa='org.apache.royale.core.IMXMLDocument',
>>> 
>>> Ta='org.apache.royale.core.IMeasurementBead',Ua='org.apache.royale.core.IParent',Va='org.apache.royale.core.IParentIUIBase',Wa='org.apache.royale.core.IPopUpHost',Xa='org.apache.royale.core.IPopUpHostParent',Ya='org.apache.royale.core.IRenderedObject',Za='org.apache.royale.core.IRoyaleElement',$a='org.apache.royale.core.IState',ab='org.apache.royale.core.IStatesImpl',bb='org.apache.royale.core.IStatesObject',cb='org.apache.royale.core.IStrand',db='org.apache.royale.core.IStrandWithModel',eb='org.apache.royale.core.IStrandWithModelView',
>>> 
>>> fb='org.apache.royale.core.IStyleObject',gb='org.apache.royale.core.IStyleableObject',hb='org.apache.royale.core.IUIBase',ib='org.apache.royale.core.IValuesImpl',jb='org.apache.royale.core.LayoutBase',kb='org.apache.royale.core.SimpleCSSValuesImpl',lb='org.apache.royale.core.UIBase',mb='org.apache.royale.core.ValuesManager',nb='org.apache.royale.core.View',ob='org.apache.royale.core.ViewBase',pb='org.apache.royale.core.WrappedHTMLElement',qb='org.apache.royale.core.layout.EdgeData',rb='org.apache.royale.core.layout.LayoutData',
>>> 
>>> sb='org.apache.royale.core.layout.MarginData',tb='org.apache.royale.core.styles.BorderStyles',ub='org.apache.royale.events.BrowserEvent',vb='org.apache.royale.events.ElementEvents',wb='org.apache.royale.events.Event',xb='org.apache.royale.events.EventDispatcher',yb='org.apache.royale.events.IBrowserEvent',zb='org.apache.royale.events.IEventDispatcher',Ab='org.apache.royale.events.IRoyaleEvent',Bb='org.apache.royale.events.ValueChangeEvent',Cb='org.apache.royale.events.ValueEvent',Db='org.apache.royale.events.utils.EventUtils',
>>> Eb='org.apache.royale.html.Label',Fb='org.apache.royale.html.beads.GroupView',Gb='org.apache.royale.html.beads.layouts.BasicLayout',Hb='org.apache.royale.utils.CSSUtils',Ib='org.apache.royale.utils.MXMLDataInterpreter',Jb='org.apache.royale.utils.StringPadder',Kb='org.apache.royale.utils.Timer',Lb='percentHeightChanged',Mb='percentWidthChanged',Nb='resizeHandler',Ob='sizeChanged',Pb='string',Qb='test_project',Rb='viewChanged',Sb='widthChanged';function
>>> l(){return function(){}}
>>> 
>>>> On Dec 1, 2021, at 7:14 PM, Josh Tynjala <jo...@bowlerhat.dev>
>>> wrote:
>>>> 
>>>>> I also noticed that none of these options seem to allow class names to
>>> be
>>>> dropped. That’s a lot of baggage being carried around for no apparent
>>>> reason.
>>>> 
>>>> It's certainly possible that I accidentally overlooked class renaming,
>>> but
>>>> that doesn't sound right to me. I'll double-check.
>>> 
>>> 
> 


Re: Compiler options for reducing release build size of Royale projects (Part 2)

Posted by Harbs <ha...@gmail.com>.
Hmm. Maybe.

Greg, I think that’s your area of expertise.

> On Dec 1, 2021, at 7:45 PM, Josh Tynjala <jo...@bowlerhat.dev> wrote:
> 
> Could those be the qname strings added to the ROYALE_CLASS_INFO object?
> 
> For example, I assume that this one:
> 
> fb='org.apache.royale.core.IStyleObject'
> 
> Comes from here:
> 
> /**
> * Metadata
> *
> * @type {Object.<string, Array.<Object>>}
> */
> org.apache.royale.core.IStyleObject.prototype.ROYALE_CLASS_INFO = { names:
> [{ name: 'IStyleObject', qName: 'org.apache.royale.core.IStyleObject',
> kind: 'interface' }] };
> 
> I'm not super familiar with the reflection system, so that's just a guess.
> 
> --
> Josh Tynjala
> Bowler Hat LLC <https://bowlerhat.dev>
> 
> 
> On Wed, Dec 1, 2021 at 9:25 AM Harbs <ha...@gmail.com> wrote:
> 
>> Maybe I’m missing a compiler option, but I compiled this:
>> 
>> <?xml version="1.0" encoding="utf-8"?>
>> <js:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
>>                xmlns:js="library://ns.apache.org/royale/basic"
>>                applicationComplete="onComplete()">
>>    <fx:Script>
>>        <![CDATA[
>>            private function onComplete():void{
>>                trace("foo");
>>            }
>>        ]]>
>>    </fx:Script>
>>    <js:valuesImpl>
>>        <js:SimpleCSSValuesImpl />
>>    </js:valuesImpl>
>>    <js:initialView>
>>        <js:View>
>>            <js:Label text="ID" id="id1" localId="id1" />
>>        </js:View>
>>    </js:initialView>
>> </js:Application>
>> 
>> with this:
>> 
>> {
>>    "config": "royale",
>>    "compilerOptions": {
>>        "debug": true,
>>        "targets": ["JSRoyale"],
>>        "source-map": true,
>>        "remove-circulars": true
>>    },
>>    "additionalOptions": "-js-output-optimization=skipAsCoercions
>> -allow-abstract-classes=true -js-vector-emulation-class=Array
>> -js-vector-index-checks=false -js-complex-implicit-coercions=false
>> -export-public-symbols=false -prevent-rename-protected-symbols=false
>> -prevent-rename-public-static-methods=false
>> -prevent-rename-public-instance-methods=false
>> -prevent-rename-public-static-variables=false
>> -prevent-rename-public-instance-variables=false
>> -prevent-rename-public-instance-accessors=false",
>>    "files":
>>    [
>>        "src/test_project.mxml"
>>    ]
>> }
>> 
>> And got this at the top of the minified code:
>> 
>> 
>> var aa='Error #1034: Type Coercion failed: cannot convert
>> ',ba='applicationComplete',ca='array',da='backgroundImage',ea='border-box',fa='childrenAdded',f='class',ha='deferredSizeHandler',ia='explicitHeightChanged',ja='explicitWidthChanged',h='function',ka='handleInitComplete',la='handleSizeChange',ma='heightChanged',na='inherit',oa='initComplete',k='interface',pa='number',qa='object',ra='org.apache.royale.core.Application',sa='org.apache.royale.core.ApplicationBase',ta='org.apache.royale.core.Bead',
>> 
>> ua='org.apache.royale.core.BeadViewBase',va='org.apache.royale.core.DispatcherBead',wa='org.apache.royale.core.ElementWrapper',xa='org.apache.royale.core.GroupBase',ya='org.apache.royale.core.HTMLElementWrapper',za='org.apache.royale.core.IApplicationView',Aa='org.apache.royale.core.IBead',Ba='org.apache.royale.core.IBeadController',Ca='org.apache.royale.core.IBeadLayout',Da='org.apache.royale.core.IBeadModel',Ea='org.apache.royale.core.IBeadView',Fa='org.apache.royale.core.IBorderPaddingMarginValuesImpl',
>> 
>> Ga='org.apache.royale.core.ICSSImpl',Ha='org.apache.royale.core.IChild',Ia='org.apache.royale.core.IContainer',Ja='org.apache.royale.core.IContentViewHost',Ka='org.apache.royale.core.IDocument',La='org.apache.royale.core.IFlexInfo',Ma='org.apache.royale.core.IId',Na='org.apache.royale.core.IInitialViewApplication',Oa='org.apache.royale.core.ILayoutChild',Pa='org.apache.royale.core.ILayoutHost',Qa='org.apache.royale.core.ILayoutParent',Ra='org.apache.royale.core.ILayoutView',Sa='org.apache.royale.core.IMXMLDocument',
>> 
>> Ta='org.apache.royale.core.IMeasurementBead',Ua='org.apache.royale.core.IParent',Va='org.apache.royale.core.IParentIUIBase',Wa='org.apache.royale.core.IPopUpHost',Xa='org.apache.royale.core.IPopUpHostParent',Ya='org.apache.royale.core.IRenderedObject',Za='org.apache.royale.core.IRoyaleElement',$a='org.apache.royale.core.IState',ab='org.apache.royale.core.IStatesImpl',bb='org.apache.royale.core.IStatesObject',cb='org.apache.royale.core.IStrand',db='org.apache.royale.core.IStrandWithModel',eb='org.apache.royale.core.IStrandWithModelView',
>> 
>> fb='org.apache.royale.core.IStyleObject',gb='org.apache.royale.core.IStyleableObject',hb='org.apache.royale.core.IUIBase',ib='org.apache.royale.core.IValuesImpl',jb='org.apache.royale.core.LayoutBase',kb='org.apache.royale.core.SimpleCSSValuesImpl',lb='org.apache.royale.core.UIBase',mb='org.apache.royale.core.ValuesManager',nb='org.apache.royale.core.View',ob='org.apache.royale.core.ViewBase',pb='org.apache.royale.core.WrappedHTMLElement',qb='org.apache.royale.core.layout.EdgeData',rb='org.apache.royale.core.layout.LayoutData',
>> 
>> sb='org.apache.royale.core.layout.MarginData',tb='org.apache.royale.core.styles.BorderStyles',ub='org.apache.royale.events.BrowserEvent',vb='org.apache.royale.events.ElementEvents',wb='org.apache.royale.events.Event',xb='org.apache.royale.events.EventDispatcher',yb='org.apache.royale.events.IBrowserEvent',zb='org.apache.royale.events.IEventDispatcher',Ab='org.apache.royale.events.IRoyaleEvent',Bb='org.apache.royale.events.ValueChangeEvent',Cb='org.apache.royale.events.ValueEvent',Db='org.apache.royale.events.utils.EventUtils',
>> Eb='org.apache.royale.html.Label',Fb='org.apache.royale.html.beads.GroupView',Gb='org.apache.royale.html.beads.layouts.BasicLayout',Hb='org.apache.royale.utils.CSSUtils',Ib='org.apache.royale.utils.MXMLDataInterpreter',Jb='org.apache.royale.utils.StringPadder',Kb='org.apache.royale.utils.Timer',Lb='percentHeightChanged',Mb='percentWidthChanged',Nb='resizeHandler',Ob='sizeChanged',Pb='string',Qb='test_project',Rb='viewChanged',Sb='widthChanged';function
>> l(){return function(){}}
>> 
>>> On Dec 1, 2021, at 7:14 PM, Josh Tynjala <jo...@bowlerhat.dev>
>> wrote:
>>> 
>>>> I also noticed that none of these options seem to allow class names to
>> be
>>> dropped. That’s a lot of baggage being carried around for no apparent
>>> reason.
>>> 
>>> It's certainly possible that I accidentally overlooked class renaming,
>> but
>>> that doesn't sound right to me. I'll double-check.
>> 
>> 


Re: Compiler options for reducing release build size of Royale projects (Part 2)

Posted by Josh Tynjala <jo...@bowlerhat.dev>.
Could those be the qname strings added to the ROYALE_CLASS_INFO object?

For example, I assume that this one:

fb='org.apache.royale.core.IStyleObject'

Comes from here:

/**
 * Metadata
 *
 * @type {Object.<string, Array.<Object>>}
 */
org.apache.royale.core.IStyleObject.prototype.ROYALE_CLASS_INFO = { names:
[{ name: 'IStyleObject', qName: 'org.apache.royale.core.IStyleObject',
kind: 'interface' }] };

I'm not super familiar with the reflection system, so that's just a guess.

--
Josh Tynjala
Bowler Hat LLC <https://bowlerhat.dev>


On Wed, Dec 1, 2021 at 9:25 AM Harbs <ha...@gmail.com> wrote:

> Maybe I’m missing a compiler option, but I compiled this:
>
> <?xml version="1.0" encoding="utf-8"?>
> <js:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
>                 xmlns:js="library://ns.apache.org/royale/basic"
>                 applicationComplete="onComplete()">
>     <fx:Script>
>         <![CDATA[
>             private function onComplete():void{
>                 trace("foo");
>             }
>         ]]>
>     </fx:Script>
>     <js:valuesImpl>
>         <js:SimpleCSSValuesImpl />
>     </js:valuesImpl>
>     <js:initialView>
>         <js:View>
>             <js:Label text="ID" id="id1" localId="id1" />
>         </js:View>
>     </js:initialView>
> </js:Application>
>
> with this:
>
> {
>     "config": "royale",
>     "compilerOptions": {
>         "debug": true,
>         "targets": ["JSRoyale"],
>         "source-map": true,
>         "remove-circulars": true
>     },
>     "additionalOptions": "-js-output-optimization=skipAsCoercions
> -allow-abstract-classes=true -js-vector-emulation-class=Array
> -js-vector-index-checks=false -js-complex-implicit-coercions=false
> -export-public-symbols=false -prevent-rename-protected-symbols=false
> -prevent-rename-public-static-methods=false
> -prevent-rename-public-instance-methods=false
> -prevent-rename-public-static-variables=false
> -prevent-rename-public-instance-variables=false
> -prevent-rename-public-instance-accessors=false",
>     "files":
>     [
>         "src/test_project.mxml"
>     ]
> }
>
> And got this at the top of the minified code:
>
>
> var aa='Error #1034: Type Coercion failed: cannot convert
> ',ba='applicationComplete',ca='array',da='backgroundImage',ea='border-box',fa='childrenAdded',f='class',ha='deferredSizeHandler',ia='explicitHeightChanged',ja='explicitWidthChanged',h='function',ka='handleInitComplete',la='handleSizeChange',ma='heightChanged',na='inherit',oa='initComplete',k='interface',pa='number',qa='object',ra='org.apache.royale.core.Application',sa='org.apache.royale.core.ApplicationBase',ta='org.apache.royale.core.Bead',
>
> ua='org.apache.royale.core.BeadViewBase',va='org.apache.royale.core.DispatcherBead',wa='org.apache.royale.core.ElementWrapper',xa='org.apache.royale.core.GroupBase',ya='org.apache.royale.core.HTMLElementWrapper',za='org.apache.royale.core.IApplicationView',Aa='org.apache.royale.core.IBead',Ba='org.apache.royale.core.IBeadController',Ca='org.apache.royale.core.IBeadLayout',Da='org.apache.royale.core.IBeadModel',Ea='org.apache.royale.core.IBeadView',Fa='org.apache.royale.core.IBorderPaddingMarginValuesImpl',
>
> Ga='org.apache.royale.core.ICSSImpl',Ha='org.apache.royale.core.IChild',Ia='org.apache.royale.core.IContainer',Ja='org.apache.royale.core.IContentViewHost',Ka='org.apache.royale.core.IDocument',La='org.apache.royale.core.IFlexInfo',Ma='org.apache.royale.core.IId',Na='org.apache.royale.core.IInitialViewApplication',Oa='org.apache.royale.core.ILayoutChild',Pa='org.apache.royale.core.ILayoutHost',Qa='org.apache.royale.core.ILayoutParent',Ra='org.apache.royale.core.ILayoutView',Sa='org.apache.royale.core.IMXMLDocument',
>
> Ta='org.apache.royale.core.IMeasurementBead',Ua='org.apache.royale.core.IParent',Va='org.apache.royale.core.IParentIUIBase',Wa='org.apache.royale.core.IPopUpHost',Xa='org.apache.royale.core.IPopUpHostParent',Ya='org.apache.royale.core.IRenderedObject',Za='org.apache.royale.core.IRoyaleElement',$a='org.apache.royale.core.IState',ab='org.apache.royale.core.IStatesImpl',bb='org.apache.royale.core.IStatesObject',cb='org.apache.royale.core.IStrand',db='org.apache.royale.core.IStrandWithModel',eb='org.apache.royale.core.IStrandWithModelView',
>
> fb='org.apache.royale.core.IStyleObject',gb='org.apache.royale.core.IStyleableObject',hb='org.apache.royale.core.IUIBase',ib='org.apache.royale.core.IValuesImpl',jb='org.apache.royale.core.LayoutBase',kb='org.apache.royale.core.SimpleCSSValuesImpl',lb='org.apache.royale.core.UIBase',mb='org.apache.royale.core.ValuesManager',nb='org.apache.royale.core.View',ob='org.apache.royale.core.ViewBase',pb='org.apache.royale.core.WrappedHTMLElement',qb='org.apache.royale.core.layout.EdgeData',rb='org.apache.royale.core.layout.LayoutData',
>
> sb='org.apache.royale.core.layout.MarginData',tb='org.apache.royale.core.styles.BorderStyles',ub='org.apache.royale.events.BrowserEvent',vb='org.apache.royale.events.ElementEvents',wb='org.apache.royale.events.Event',xb='org.apache.royale.events.EventDispatcher',yb='org.apache.royale.events.IBrowserEvent',zb='org.apache.royale.events.IEventDispatcher',Ab='org.apache.royale.events.IRoyaleEvent',Bb='org.apache.royale.events.ValueChangeEvent',Cb='org.apache.royale.events.ValueEvent',Db='org.apache.royale.events.utils.EventUtils',
> Eb='org.apache.royale.html.Label',Fb='org.apache.royale.html.beads.GroupView',Gb='org.apache.royale.html.beads.layouts.BasicLayout',Hb='org.apache.royale.utils.CSSUtils',Ib='org.apache.royale.utils.MXMLDataInterpreter',Jb='org.apache.royale.utils.StringPadder',Kb='org.apache.royale.utils.Timer',Lb='percentHeightChanged',Mb='percentWidthChanged',Nb='resizeHandler',Ob='sizeChanged',Pb='string',Qb='test_project',Rb='viewChanged',Sb='widthChanged';function
> l(){return function(){}}
>
> > On Dec 1, 2021, at 7:14 PM, Josh Tynjala <jo...@bowlerhat.dev>
> wrote:
> >
> >> I also noticed that none of these options seem to allow class names to
> be
> > dropped. That’s a lot of baggage being carried around for no apparent
> > reason.
> >
> > It's certainly possible that I accidentally overlooked class renaming,
> but
> > that doesn't sound right to me. I'll double-check.
>
>

Re: Compiler options for reducing release build size of Royale projects (Part 2)

Posted by Harbs <ha...@gmail.com>.
Maybe I’m missing a compiler option, but I compiled this:

<?xml version="1.0" encoding="utf-8"?>
<js:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
                xmlns:js="library://ns.apache.org/royale/basic"
                applicationComplete="onComplete()">
    <fx:Script>
        <![CDATA[
            private function onComplete():void{
                trace("foo");
            }
        ]]>
    </fx:Script>
    <js:valuesImpl>
        <js:SimpleCSSValuesImpl />
    </js:valuesImpl>
    <js:initialView>
        <js:View>
            <js:Label text="ID" id="id1" localId="id1" />
        </js:View>
    </js:initialView>
</js:Application>

with this:

{
    "config": "royale",
    "compilerOptions": {
        "debug": true,
        "targets": ["JSRoyale"],
        "source-map": true,
        "remove-circulars": true
    },
    "additionalOptions": "-js-output-optimization=skipAsCoercions -allow-abstract-classes=true -js-vector-emulation-class=Array -js-vector-index-checks=false -js-complex-implicit-coercions=false -export-public-symbols=false -prevent-rename-protected-symbols=false -prevent-rename-public-static-methods=false -prevent-rename-public-instance-methods=false -prevent-rename-public-static-variables=false -prevent-rename-public-instance-variables=false -prevent-rename-public-instance-accessors=false",
    "files":
    [
        "src/test_project.mxml"
    ]
}

And got this at the top of the minified code:


var aa='Error #1034: Type Coercion failed: cannot convert ',ba='applicationComplete',ca='array',da='backgroundImage',ea='border-box',fa='childrenAdded',f='class',ha='deferredSizeHandler',ia='explicitHeightChanged',ja='explicitWidthChanged',h='function',ka='handleInitComplete',la='handleSizeChange',ma='heightChanged',na='inherit',oa='initComplete',k='interface',pa='number',qa='object',ra='org.apache.royale.core.Application',sa='org.apache.royale.core.ApplicationBase',ta='org.apache.royale.core.Bead',
ua='org.apache.royale.core.BeadViewBase',va='org.apache.royale.core.DispatcherBead',wa='org.apache.royale.core.ElementWrapper',xa='org.apache.royale.core.GroupBase',ya='org.apache.royale.core.HTMLElementWrapper',za='org.apache.royale.core.IApplicationView',Aa='org.apache.royale.core.IBead',Ba='org.apache.royale.core.IBeadController',Ca='org.apache.royale.core.IBeadLayout',Da='org.apache.royale.core.IBeadModel',Ea='org.apache.royale.core.IBeadView',Fa='org.apache.royale.core.IBorderPaddingMarginValuesImpl',
Ga='org.apache.royale.core.ICSSImpl',Ha='org.apache.royale.core.IChild',Ia='org.apache.royale.core.IContainer',Ja='org.apache.royale.core.IContentViewHost',Ka='org.apache.royale.core.IDocument',La='org.apache.royale.core.IFlexInfo',Ma='org.apache.royale.core.IId',Na='org.apache.royale.core.IInitialViewApplication',Oa='org.apache.royale.core.ILayoutChild',Pa='org.apache.royale.core.ILayoutHost',Qa='org.apache.royale.core.ILayoutParent',Ra='org.apache.royale.core.ILayoutView',Sa='org.apache.royale.core.IMXMLDocument',
Ta='org.apache.royale.core.IMeasurementBead',Ua='org.apache.royale.core.IParent',Va='org.apache.royale.core.IParentIUIBase',Wa='org.apache.royale.core.IPopUpHost',Xa='org.apache.royale.core.IPopUpHostParent',Ya='org.apache.royale.core.IRenderedObject',Za='org.apache.royale.core.IRoyaleElement',$a='org.apache.royale.core.IState',ab='org.apache.royale.core.IStatesImpl',bb='org.apache.royale.core.IStatesObject',cb='org.apache.royale.core.IStrand',db='org.apache.royale.core.IStrandWithModel',eb='org.apache.royale.core.IStrandWithModelView',
fb='org.apache.royale.core.IStyleObject',gb='org.apache.royale.core.IStyleableObject',hb='org.apache.royale.core.IUIBase',ib='org.apache.royale.core.IValuesImpl',jb='org.apache.royale.core.LayoutBase',kb='org.apache.royale.core.SimpleCSSValuesImpl',lb='org.apache.royale.core.UIBase',mb='org.apache.royale.core.ValuesManager',nb='org.apache.royale.core.View',ob='org.apache.royale.core.ViewBase',pb='org.apache.royale.core.WrappedHTMLElement',qb='org.apache.royale.core.layout.EdgeData',rb='org.apache.royale.core.layout.LayoutData',
sb='org.apache.royale.core.layout.MarginData',tb='org.apache.royale.core.styles.BorderStyles',ub='org.apache.royale.events.BrowserEvent',vb='org.apache.royale.events.ElementEvents',wb='org.apache.royale.events.Event',xb='org.apache.royale.events.EventDispatcher',yb='org.apache.royale.events.IBrowserEvent',zb='org.apache.royale.events.IEventDispatcher',Ab='org.apache.royale.events.IRoyaleEvent',Bb='org.apache.royale.events.ValueChangeEvent',Cb='org.apache.royale.events.ValueEvent',Db='org.apache.royale.events.utils.EventUtils',
Eb='org.apache.royale.html.Label',Fb='org.apache.royale.html.beads.GroupView',Gb='org.apache.royale.html.beads.layouts.BasicLayout',Hb='org.apache.royale.utils.CSSUtils',Ib='org.apache.royale.utils.MXMLDataInterpreter',Jb='org.apache.royale.utils.StringPadder',Kb='org.apache.royale.utils.Timer',Lb='percentHeightChanged',Mb='percentWidthChanged',Nb='resizeHandler',Ob='sizeChanged',Pb='string',Qb='test_project',Rb='viewChanged',Sb='widthChanged';function l(){return function(){}}

> On Dec 1, 2021, at 7:14 PM, Josh Tynjala <jo...@bowlerhat.dev> wrote:
> 
>> I also noticed that none of these options seem to allow class names to be
> dropped. That’s a lot of baggage being carried around for no apparent
> reason.
> 
> It's certainly possible that I accidentally overlooked class renaming, but
> that doesn't sound right to me. I'll double-check.


Re: Compiler options for reducing release build size of Royale projects (Part 2)

Posted by Josh Tynjala <jo...@bowlerhat.dev>.
Thanks for sharing your results! I'm glad that my work has led to such a
large improvement for your app.

--
Josh Tynjala
Bowler Hat LLC <https://bowlerhat.dev>


On Tue, Dec 28, 2021 at 1:36 PM Harbs <ha...@gmail.com> wrote:

> After 2 weeks of intense work, I got my app fully functional with the
> options below.
>
> Here’s in short what I did:
>
> 1. I audited as many cases of quoted access I could in the unminified JS
> code. Any place where it was accessing something on a class/instance was
> because the compiler couldn’t figure out the type.
> 2. I added types to all the places I could find. I basically eliminated
> every use of :Object and :* that I could.
> 3. I used Vectors where I could (using the
> -js-vector-emulation-class=Array option)
> 4. I removed unknown class accessors (no looping through classes and
> calling static methods)
> 5. Removed all the dynamic bracket access and assignment. (no for-ins on
> class instances, etc.)
>
> In my travels I discovered that:
> 1. Jewel does not look like it can be aggressively minified. (Spectrum
> can.)
> 2. MX/Spark does not look like it can either.
> 3. I need to heavily modify my already modified version of TLF to get it
> to work with minification.
> 4. There was some unnecessary Reflection and Vector dependencies in
> framework code which I fixed.
> 5. Class names is a prime candidate for code removal, and (besides
> reflection) the current roadblock with that is SimpleCSSValuesImpl which
> accesses ROYALE_CLASS_INFO. If we can eliminate that, I’d save 66KB (12KB
> gzipped) in my app.
> 6. It’s worthwhile to use protected methods for event listener callbacks,
> because the long-winded private method names end up in the minified code.
> (I still need to address this.)
>
> End results:
>
> Before my effort, my app was 2,903,814 bytes and 777,071 bytes when gzipped
> Afterwards: 1,989,596 bytes and 621,851 bytes gzipped
>
> That’s a savings of 1MB before gzipping (about 1/3) and 155KB after
> gzipping. (about 20% reduction)
>
> If we can get rid of the class names we can get down to: 1,923,653
> bytes/610,493 bytes.
>
> A little over 600KB is a totally reasonable size for an application of
> this size and complexity. The Flash version was MANY times that and has a
> LOT less code.
>
> This turned into somewhat of an obsession for me, but I’m pleased with the
> results. :-)
>
> HTH,
> Harbs
> > On Dec 16, 2021, at 8:54 PM, Harbs <ha...@gmail.com> wrote:
> >
> > Well I spent more time. Besides the XML issues which are pretty much
> resolved, I ran into:
> >
> > 1. I have a setter in a class which was removed by the goog dead code
> removal. I worked around it by turning the setter into a method. I’ll see
> if I can come up with a minimal test case on that.
> >
> > 2. I have a library which has a LOT of dynamic pieces. I spent a LONG
> time trying to assign types to places where I was getting runtime errors. I
> now got to the point where there’s no more runtime errors, but it’s still
> not working and I’m pretty sure it’s because I missed some typing.
> >
> > Is there any way to keep public accessors on one library or specific
> classes? I’d like to compile my app with:
> >
> > "-js-dynamic-access-unknown-members=true",
> > "-export-public-symbols=false",
> > "-prevent-rename-protected-symbols=false",
> > "-prevent-rename-public-symbols=false",
> > "-prevent-rename-internal-symbols=false"
> >
> > but be able to exclude a list of classes from that.
> >
> >> On Dec 1, 2021, at 7:47 PM, Harbs <harbs.lists@gmail.com <mailto:
> harbs.lists@gmail.com>> wrote:
> >>
> >> I’m pretty sure the issue is related to events not being properly
> handled. Although blinding might be worth looking into.
> >>
> >> I’ll look into it some more when I have more time.
> >>
> >> Thanks!
> >>
> >>> On Dec 1, 2021, at 7:14 PM, Josh Tynjala <joshtynjala@bowlerhat.dev
> <ma...@bowlerhat.dev>> wrote:
> >>>
> >>>> It *almost* works. I found and fixed two cases of bracket access which
> >>> broke things. Now I’m getting no errors, but it’s still not quite
> working.
> >>> I’m guessing it’s something simple that I need to fix.
> >>>
> >>> Have you tried a smaller set of prevent-rename options? That might
> help you
> >>> narrow things down, if things start working better. I'd try allowing
> public
> >>> variables, and maybe public accessors, to be renamed first, and see if
> that
> >>> works. Those types of symbols are most likely to be getting accessed
> >>> dynamically somehow. However, I don't really have much in the way of
> tips
> >>> to narrow it down from there. ConstantBinding would be one thing to
> look
> >>> out for, which I mentioned in my summary.
> >>
> >
>
>

Re: Compiler options for reducing release build size of Royale projects (Part 2)

Posted by Harbs <ha...@gmail.com>.
Glad to hear. :-)

> On Dec 29, 2021, at 11:17 PM, Maria Jose Esteve <mj...@iest.com> wrote:
> 
> I love this!!! thanks Harb
> 
> Hiedra
> 
> -----Mensaje original-----
> De: Harbs <ha...@gmail.com> 
> Enviado el: miércoles, 29 de diciembre de 2021 12:11
> Para: Apache Royale Development <de...@royale.apache.org>
> Asunto: Re: Compiler options for reducing release build size of Royale projects (Part 2)
> 
> Done:
> https://apache.github.io/royale-docs/create-an-application/optimizations/minification
> 
>> On Dec 29, 2021, at 8:11 AM, Harbs <ha...@gmail.com> wrote:
>> 
>> I plan on writing a minification documentation page which explains all of this and the take-aways from my (and Josh’s) efforts.
>> 
>>> On Dec 29, 2021, at 8:09 AM, Harbs <harbs.lists@gmail.com <ma...@gmail.com>> wrote:
>>> 
>>> Let me qualify that.
>>> 
>>> If you use "-js-dynamic-access-unknown-members=true” all untyped members are quoted.
>>> 
>>> If you don’t use "-js-dynamic-access-unknown-members=true”, then the 
>>> minification even without exports should work fine, but then you need 
>>> to make sure you quote any Object members where the name is 
>>> significant (i.e. data coming from JSON, etc.)
>>> 
>>> If you need "-js-dynamic-access-unknown-members=true”, then you will get accessor mismatches unless you consistently use data types and not “Object” or “*”. Included in that is access to Array members (i.e. myArray[i].fooBaz() is a no-no because it will get quoted on output). Neither Jewel nor MX/Spark was written with that in mind. It’s fixable, but it will take time. I fixed the general framework classes, but those component sets were not within scope for me.
>>> 
>>> HTH,
>>> Harbs
>>> 
>>>> On Dec 29, 2021, at 8:01 AM, Yishay Weiss <yishayjobs@hotmail.com <ma...@hotmail.com>> wrote:
>>>> 
>>>>> 1. Jewel does not look like it can be aggressively minified. 
>>>>> (Spectrum can.) 2. MX/Spark does not look like it can either.
>>>> 
>>>> Can you explain this?
>>>> 
>>>> 
>>>> From: Harbs<mailto:harbs.lists@gmail.com 
>>>> <ma...@gmail.com>>
>>>> Sent: Tuesday, December 28, 2021 11:36 PM
>>>> To: Apache Royale Development<mailto:dev@royale.apache.org 
>>>> <ma...@royale.apache.org>>
>>>> Subject: Re: Compiler options for reducing release build size of 
>>>> Royale projects (Part 2)
>>>> 
>>>> After 2 weeks of intense work, I got my app fully functional with the options below.
>>>> 
>>>> Here’s in short what I did:
>>>> 
>>>> 1. I audited as many cases of quoted access I could in the unminified JS code. Any place where it was accessing something on a class/instance was because the compiler couldn’t figure out the type.
>>>> 2. I added types to all the places I could find. I basically eliminated every use of :Object and :* that I could.
>>>> 3. I used Vectors where I could (using the 
>>>> -js-vector-emulation-class=Array option) 4. I removed unknown class 
>>>> accessors (no looping through classes and calling static methods) 5. 
>>>> Removed all the dynamic bracket access and assignment. (no for-ins 
>>>> on class instances, etc.)
>>>> 
>>>> In my travels I discovered that:
>>>> 1. Jewel does not look like it can be aggressively minified. 
>>>> (Spectrum can.) 2. MX/Spark does not look like it can either.
>>>> 3. I need to heavily modify my already modified version of TLF to get it to work with minification.
>>>> 4. There was some unnecessary Reflection and Vector dependencies in framework code which I fixed.
>>>> 5. Class names is a prime candidate for code removal, and (besides reflection) the current roadblock with that is SimpleCSSValuesImpl which accesses ROYALE_CLASS_INFO. If we can eliminate that, I’d save 66KB (12KB gzipped) in my app.
>>>> 6. It’s worthwhile to use protected methods for event listener 
>>>> callbacks, because the long-winded private method names end up in 
>>>> the minified code. (I still need to address this.)
>>>> 
>>>> End results:
>>>> 
>>>> Before my effort, my app was 2,903,814 bytes and 777,071 bytes when 
>>>> gzipped
>>>> Afterwards: 1,989,596 bytes and 621,851 bytes gzipped
>>>> 
>>>> That’s a savings of 1MB before gzipping (about 1/3) and 155KB after 
>>>> gzipping. (about 20% reduction)
>>>> 
>>>> If we can get rid of the class names we can get down to: 1,923,653 bytes/610,493 bytes.
>>>> 
>>>> A little over 600KB is a totally reasonable size for an application of this size and complexity. The Flash version was MANY times that and has a LOT less code.
>>>> 
>>>> This turned into somewhat of an obsession for me, but I’m pleased 
>>>> with the results. :-)
>>>> 
>>>> HTH,
>>>> Harbs
>>>>> On Dec 16, 2021, at 8:54 PM, Harbs <harbs.lists@gmail.com <ma...@gmail.com>> wrote:
>>>>> 
>>>>> Well I spent more time. Besides the XML issues which are pretty much resolved, I ran into:
>>>>> 
>>>>> 1. I have a setter in a class which was removed by the goog dead code removal. I worked around it by turning the setter into a method. I’ll see if I can come up with a minimal test case on that.
>>>>> 
>>>>> 2. I have a library which has a LOT of dynamic pieces. I spent a LONG time trying to assign types to places where I was getting runtime errors. I now got to the point where there’s no more runtime errors, but it’s still not working and I’m pretty sure it’s because I missed some typing.
>>>>> 
>>>>> Is there any way to keep public accessors on one library or specific classes? I’d like to compile my app with:
>>>>> 
>>>>> "-js-dynamic-access-unknown-members=true",
>>>>> "-export-public-symbols=false",
>>>>> "-prevent-rename-protected-symbols=false",
>>>>> "-prevent-rename-public-symbols=false",
>>>>> "-prevent-rename-internal-symbols=false"
>>>>> 
>>>>> but be able to exclude a list of classes from that.
>>>>> 
>>>>>> On Dec 1, 2021, at 7:47 PM, Harbs <harbs.lists@gmail.com <ma...@gmail.com> <mailto:harbs.lists@gmail.com <ma...@gmail.com>>> wrote:
>>>>>> 
>>>>>> I’m pretty sure the issue is related to events not being properly handled. Although blinding might be worth looking into.
>>>>>> 
>>>>>> I’ll look into it some more when I have more time.
>>>>>> 
>>>>>> Thanks!
>>>>>> 
>>>>>>> On Dec 1, 2021, at 7:14 PM, Josh Tynjala <joshtynjala@bowlerhat.dev <ma...@bowlerhat.dev> <mailto:joshtynjala@bowlerhat.dev <ma...@bowlerhat.dev>>> wrote:
>>>>>>> 
>>>>>>>> It *almost* works. I found and fixed two cases of bracket access 
>>>>>>>> which
>>>>>>> broke things. Now I’m getting no errors, but it’s still not quite working.
>>>>>>> I’m guessing it’s something simple that I need to fix.
>>>>>>> 
>>>>>>> Have you tried a smaller set of prevent-rename options? That 
>>>>>>> might help you narrow things down, if things start working 
>>>>>>> better. I'd try allowing public variables, and maybe public 
>>>>>>> accessors, to be renamed first, and see if that works. Those 
>>>>>>> types of symbols are most likely to be getting accessed 
>>>>>>> dynamically somehow. However, I don't really have much in the way 
>>>>>>> of tips to narrow it down from there. ConstantBinding would be one thing to look out for, which I mentioned in my summary.
>>> 
>> 
> 


RE: Compiler options for reducing release build size of Royale projects (Part 2)

Posted by Maria Jose Esteve <mj...@iest.com>.
I love this!!! thanks Harb

Hiedra

-----Mensaje original-----
De: Harbs <ha...@gmail.com> 
Enviado el: miércoles, 29 de diciembre de 2021 12:11
Para: Apache Royale Development <de...@royale.apache.org>
Asunto: Re: Compiler options for reducing release build size of Royale projects (Part 2)

Done:
https://apache.github.io/royale-docs/create-an-application/optimizations/minification

> On Dec 29, 2021, at 8:11 AM, Harbs <ha...@gmail.com> wrote:
> 
> I plan on writing a minification documentation page which explains all of this and the take-aways from my (and Josh’s) efforts.
> 
>> On Dec 29, 2021, at 8:09 AM, Harbs <harbs.lists@gmail.com <ma...@gmail.com>> wrote:
>> 
>> Let me qualify that.
>> 
>> If you use "-js-dynamic-access-unknown-members=true” all untyped members are quoted.
>> 
>> If you don’t use "-js-dynamic-access-unknown-members=true”, then the 
>> minification even without exports should work fine, but then you need 
>> to make sure you quote any Object members where the name is 
>> significant (i.e. data coming from JSON, etc.)
>> 
>> If you need "-js-dynamic-access-unknown-members=true”, then you will get accessor mismatches unless you consistently use data types and not “Object” or “*”. Included in that is access to Array members (i.e. myArray[i].fooBaz() is a no-no because it will get quoted on output). Neither Jewel nor MX/Spark was written with that in mind. It’s fixable, but it will take time. I fixed the general framework classes, but those component sets were not within scope for me.
>> 
>> HTH,
>> Harbs
>> 
>>> On Dec 29, 2021, at 8:01 AM, Yishay Weiss <yishayjobs@hotmail.com <ma...@hotmail.com>> wrote:
>>> 
>>>> 1. Jewel does not look like it can be aggressively minified. 
>>>> (Spectrum can.) 2. MX/Spark does not look like it can either.
>>> 
>>> Can you explain this?
>>> 
>>> 
>>> From: Harbs<mailto:harbs.lists@gmail.com 
>>> <ma...@gmail.com>>
>>> Sent: Tuesday, December 28, 2021 11:36 PM
>>> To: Apache Royale Development<mailto:dev@royale.apache.org 
>>> <ma...@royale.apache.org>>
>>> Subject: Re: Compiler options for reducing release build size of 
>>> Royale projects (Part 2)
>>> 
>>> After 2 weeks of intense work, I got my app fully functional with the options below.
>>> 
>>> Here’s in short what I did:
>>> 
>>> 1. I audited as many cases of quoted access I could in the unminified JS code. Any place where it was accessing something on a class/instance was because the compiler couldn’t figure out the type.
>>> 2. I added types to all the places I could find. I basically eliminated every use of :Object and :* that I could.
>>> 3. I used Vectors where I could (using the 
>>> -js-vector-emulation-class=Array option) 4. I removed unknown class 
>>> accessors (no looping through classes and calling static methods) 5. 
>>> Removed all the dynamic bracket access and assignment. (no for-ins 
>>> on class instances, etc.)
>>> 
>>> In my travels I discovered that:
>>> 1. Jewel does not look like it can be aggressively minified. 
>>> (Spectrum can.) 2. MX/Spark does not look like it can either.
>>> 3. I need to heavily modify my already modified version of TLF to get it to work with minification.
>>> 4. There was some unnecessary Reflection and Vector dependencies in framework code which I fixed.
>>> 5. Class names is a prime candidate for code removal, and (besides reflection) the current roadblock with that is SimpleCSSValuesImpl which accesses ROYALE_CLASS_INFO. If we can eliminate that, I’d save 66KB (12KB gzipped) in my app.
>>> 6. It’s worthwhile to use protected methods for event listener 
>>> callbacks, because the long-winded private method names end up in 
>>> the minified code. (I still need to address this.)
>>> 
>>> End results:
>>> 
>>> Before my effort, my app was 2,903,814 bytes and 777,071 bytes when 
>>> gzipped
>>> Afterwards: 1,989,596 bytes and 621,851 bytes gzipped
>>> 
>>> That’s a savings of 1MB before gzipping (about 1/3) and 155KB after 
>>> gzipping. (about 20% reduction)
>>> 
>>> If we can get rid of the class names we can get down to: 1,923,653 bytes/610,493 bytes.
>>> 
>>> A little over 600KB is a totally reasonable size for an application of this size and complexity. The Flash version was MANY times that and has a LOT less code.
>>> 
>>> This turned into somewhat of an obsession for me, but I’m pleased 
>>> with the results. :-)
>>> 
>>> HTH,
>>> Harbs
>>>> On Dec 16, 2021, at 8:54 PM, Harbs <harbs.lists@gmail.com <ma...@gmail.com>> wrote:
>>>> 
>>>> Well I spent more time. Besides the XML issues which are pretty much resolved, I ran into:
>>>> 
>>>> 1. I have a setter in a class which was removed by the goog dead code removal. I worked around it by turning the setter into a method. I’ll see if I can come up with a minimal test case on that.
>>>> 
>>>> 2. I have a library which has a LOT of dynamic pieces. I spent a LONG time trying to assign types to places where I was getting runtime errors. I now got to the point where there’s no more runtime errors, but it’s still not working and I’m pretty sure it’s because I missed some typing.
>>>> 
>>>> Is there any way to keep public accessors on one library or specific classes? I’d like to compile my app with:
>>>> 
>>>> "-js-dynamic-access-unknown-members=true",
>>>> "-export-public-symbols=false",
>>>> "-prevent-rename-protected-symbols=false",
>>>> "-prevent-rename-public-symbols=false",
>>>> "-prevent-rename-internal-symbols=false"
>>>> 
>>>> but be able to exclude a list of classes from that.
>>>> 
>>>>> On Dec 1, 2021, at 7:47 PM, Harbs <harbs.lists@gmail.com <ma...@gmail.com> <mailto:harbs.lists@gmail.com <ma...@gmail.com>>> wrote:
>>>>> 
>>>>> I’m pretty sure the issue is related to events not being properly handled. Although blinding might be worth looking into.
>>>>> 
>>>>> I’ll look into it some more when I have more time.
>>>>> 
>>>>> Thanks!
>>>>> 
>>>>>> On Dec 1, 2021, at 7:14 PM, Josh Tynjala <joshtynjala@bowlerhat.dev <ma...@bowlerhat.dev> <mailto:joshtynjala@bowlerhat.dev <ma...@bowlerhat.dev>>> wrote:
>>>>>> 
>>>>>>> It *almost* works. I found and fixed two cases of bracket access 
>>>>>>> which
>>>>>> broke things. Now I’m getting no errors, but it’s still not quite working.
>>>>>> I’m guessing it’s something simple that I need to fix.
>>>>>> 
>>>>>> Have you tried a smaller set of prevent-rename options? That 
>>>>>> might help you narrow things down, if things start working 
>>>>>> better. I'd try allowing public variables, and maybe public 
>>>>>> accessors, to be renamed first, and see if that works. Those 
>>>>>> types of symbols are most likely to be getting accessed 
>>>>>> dynamically somehow. However, I don't really have much in the way 
>>>>>> of tips to narrow it down from there. ConstantBinding would be one thing to look out for, which I mentioned in my summary.
>> 
> 


Re: Compiler options for reducing release build size of Royale projects (Part 2)

Posted by Harbs <ha...@gmail.com>.
Done:
https://apache.github.io/royale-docs/create-an-application/optimizations/minification

> On Dec 29, 2021, at 8:11 AM, Harbs <ha...@gmail.com> wrote:
> 
> I plan on writing a minification documentation page which explains all of this and the take-aways from my (and Josh’s) efforts.
> 
>> On Dec 29, 2021, at 8:09 AM, Harbs <harbs.lists@gmail.com <ma...@gmail.com>> wrote:
>> 
>> Let me qualify that.
>> 
>> If you use "-js-dynamic-access-unknown-members=true” all untyped members are quoted.
>> 
>> If you don’t use "-js-dynamic-access-unknown-members=true”, then the minification even without exports should work fine, but then you need to make sure you quote any Object members where the name is significant (i.e. data coming from JSON, etc.)
>> 
>> If you need "-js-dynamic-access-unknown-members=true”, then you will get accessor mismatches unless you consistently use data types and not “Object” or “*”. Included in that is access to Array members (i.e. myArray[i].fooBaz() is a no-no because it will get quoted on output). Neither Jewel nor MX/Spark was written with that in mind. It’s fixable, but it will take time. I fixed the general framework classes, but those component sets were not within scope for me.
>> 
>> HTH,
>> Harbs
>> 
>>> On Dec 29, 2021, at 8:01 AM, Yishay Weiss <yishayjobs@hotmail.com <ma...@hotmail.com>> wrote:
>>> 
>>>> 1. Jewel does not look like it can be aggressively minified. (Spectrum can.)
>>>> 2. MX/Spark does not look like it can either.
>>> 
>>> Can you explain this?
>>> 
>>> 
>>> From: Harbs<mailto:harbs.lists@gmail.com <ma...@gmail.com>>
>>> Sent: Tuesday, December 28, 2021 11:36 PM
>>> To: Apache Royale Development<mailto:dev@royale.apache.org <ma...@royale.apache.org>>
>>> Subject: Re: Compiler options for reducing release build size of Royale projects (Part 2)
>>> 
>>> After 2 weeks of intense work, I got my app fully functional with the options below.
>>> 
>>> Here’s in short what I did:
>>> 
>>> 1. I audited as many cases of quoted access I could in the unminified JS code. Any place where it was accessing something on a class/instance was because the compiler couldn’t figure out the type.
>>> 2. I added types to all the places I could find. I basically eliminated every use of :Object and :* that I could.
>>> 3. I used Vectors where I could (using the -js-vector-emulation-class=Array option)
>>> 4. I removed unknown class accessors (no looping through classes and calling static methods)
>>> 5. Removed all the dynamic bracket access and assignment. (no for-ins on class instances, etc.)
>>> 
>>> In my travels I discovered that:
>>> 1. Jewel does not look like it can be aggressively minified. (Spectrum can.)
>>> 2. MX/Spark does not look like it can either.
>>> 3. I need to heavily modify my already modified version of TLF to get it to work with minification.
>>> 4. There was some unnecessary Reflection and Vector dependencies in framework code which I fixed.
>>> 5. Class names is a prime candidate for code removal, and (besides reflection) the current roadblock with that is SimpleCSSValuesImpl which accesses ROYALE_CLASS_INFO. If we can eliminate that, I’d save 66KB (12KB gzipped) in my app.
>>> 6. It’s worthwhile to use protected methods for event listener callbacks, because the long-winded private method names end up in the minified code. (I still need to address this.)
>>> 
>>> End results:
>>> 
>>> Before my effort, my app was 2,903,814 bytes and 777,071 bytes when gzipped
>>> Afterwards: 1,989,596 bytes and 621,851 bytes gzipped
>>> 
>>> That’s a savings of 1MB before gzipping (about 1/3) and 155KB after gzipping. (about 20% reduction)
>>> 
>>> If we can get rid of the class names we can get down to: 1,923,653 bytes/610,493 bytes.
>>> 
>>> A little over 600KB is a totally reasonable size for an application of this size and complexity. The Flash version was MANY times that and has a LOT less code.
>>> 
>>> This turned into somewhat of an obsession for me, but I’m pleased with the results. :-)
>>> 
>>> HTH,
>>> Harbs
>>>> On Dec 16, 2021, at 8:54 PM, Harbs <harbs.lists@gmail.com <ma...@gmail.com>> wrote:
>>>> 
>>>> Well I spent more time. Besides the XML issues which are pretty much resolved, I ran into:
>>>> 
>>>> 1. I have a setter in a class which was removed by the goog dead code removal. I worked around it by turning the setter into a method. I’ll see if I can come up with a minimal test case on that.
>>>> 
>>>> 2. I have a library which has a LOT of dynamic pieces. I spent a LONG time trying to assign types to places where I was getting runtime errors. I now got to the point where there’s no more runtime errors, but it’s still not working and I’m pretty sure it’s because I missed some typing.
>>>> 
>>>> Is there any way to keep public accessors on one library or specific classes? I’d like to compile my app with:
>>>> 
>>>> "-js-dynamic-access-unknown-members=true",
>>>> "-export-public-symbols=false",
>>>> "-prevent-rename-protected-symbols=false",
>>>> "-prevent-rename-public-symbols=false",
>>>> "-prevent-rename-internal-symbols=false"
>>>> 
>>>> but be able to exclude a list of classes from that.
>>>> 
>>>>> On Dec 1, 2021, at 7:47 PM, Harbs <harbs.lists@gmail.com <ma...@gmail.com> <mailto:harbs.lists@gmail.com <ma...@gmail.com>>> wrote:
>>>>> 
>>>>> I’m pretty sure the issue is related to events not being properly handled. Although blinding might be worth looking into.
>>>>> 
>>>>> I’ll look into it some more when I have more time.
>>>>> 
>>>>> Thanks!
>>>>> 
>>>>>> On Dec 1, 2021, at 7:14 PM, Josh Tynjala <joshtynjala@bowlerhat.dev <ma...@bowlerhat.dev> <mailto:joshtynjala@bowlerhat.dev <ma...@bowlerhat.dev>>> wrote:
>>>>>> 
>>>>>>> It *almost* works. I found and fixed two cases of bracket access which
>>>>>> broke things. Now I’m getting no errors, but it’s still not quite working.
>>>>>> I’m guessing it’s something simple that I need to fix.
>>>>>> 
>>>>>> Have you tried a smaller set of prevent-rename options? That might help you
>>>>>> narrow things down, if things start working better. I'd try allowing public
>>>>>> variables, and maybe public accessors, to be renamed first, and see if that
>>>>>> works. Those types of symbols are most likely to be getting accessed
>>>>>> dynamically somehow. However, I don't really have much in the way of tips
>>>>>> to narrow it down from there. ConstantBinding would be one thing to look
>>>>>> out for, which I mentioned in my summary.
>> 
> 


Re: Compiler options for reducing release build size of Royale projects (Part 2)

Posted by Harbs <ha...@gmail.com>.
I plan on writing a minification documentation page which explains all of this and the take-aways from my (and Josh’s) efforts.

> On Dec 29, 2021, at 8:09 AM, Harbs <ha...@gmail.com> wrote:
> 
> Let me qualify that.
> 
> If you use "-js-dynamic-access-unknown-members=true” all untyped members are quoted.
> 
> If you don’t use "-js-dynamic-access-unknown-members=true”, then the minification even without exports should work fine, but then you need to make sure you quote any Object members where the name is significant (i.e. data coming from JSON, etc.)
> 
> If you need "-js-dynamic-access-unknown-members=true”, then you will get accessor mismatches unless you consistently use data types and not “Object” or “*”. Included in that is access to Array members (i.e. myArray[i].fooBaz() is a no-no because it will get quoted on output). Neither Jewel nor MX/Spark was written with that in mind. It’s fixable, but it will take time. I fixed the general framework classes, but those component sets were not within scope for me.
> 
> HTH,
> Harbs
> 
>> On Dec 29, 2021, at 8:01 AM, Yishay Weiss <yishayjobs@hotmail.com <ma...@hotmail.com>> wrote:
>> 
>>> 1. Jewel does not look like it can be aggressively minified. (Spectrum can.)
>>> 2. MX/Spark does not look like it can either.
>> 
>> Can you explain this?
>> 
>> 
>> From: Harbs<mailto:harbs.lists@gmail.com <ma...@gmail.com>>
>> Sent: Tuesday, December 28, 2021 11:36 PM
>> To: Apache Royale Development<mailto:dev@royale.apache.org <ma...@royale.apache.org>>
>> Subject: Re: Compiler options for reducing release build size of Royale projects (Part 2)
>> 
>> After 2 weeks of intense work, I got my app fully functional with the options below.
>> 
>> Here’s in short what I did:
>> 
>> 1. I audited as many cases of quoted access I could in the unminified JS code. Any place where it was accessing something on a class/instance was because the compiler couldn’t figure out the type.
>> 2. I added types to all the places I could find. I basically eliminated every use of :Object and :* that I could.
>> 3. I used Vectors where I could (using the -js-vector-emulation-class=Array option)
>> 4. I removed unknown class accessors (no looping through classes and calling static methods)
>> 5. Removed all the dynamic bracket access and assignment. (no for-ins on class instances, etc.)
>> 
>> In my travels I discovered that:
>> 1. Jewel does not look like it can be aggressively minified. (Spectrum can.)
>> 2. MX/Spark does not look like it can either.
>> 3. I need to heavily modify my already modified version of TLF to get it to work with minification.
>> 4. There was some unnecessary Reflection and Vector dependencies in framework code which I fixed.
>> 5. Class names is a prime candidate for code removal, and (besides reflection) the current roadblock with that is SimpleCSSValuesImpl which accesses ROYALE_CLASS_INFO. If we can eliminate that, I’d save 66KB (12KB gzipped) in my app.
>> 6. It’s worthwhile to use protected methods for event listener callbacks, because the long-winded private method names end up in the minified code. (I still need to address this.)
>> 
>> End results:
>> 
>> Before my effort, my app was 2,903,814 bytes and 777,071 bytes when gzipped
>> Afterwards: 1,989,596 bytes and 621,851 bytes gzipped
>> 
>> That’s a savings of 1MB before gzipping (about 1/3) and 155KB after gzipping. (about 20% reduction)
>> 
>> If we can get rid of the class names we can get down to: 1,923,653 bytes/610,493 bytes.
>> 
>> A little over 600KB is a totally reasonable size for an application of this size and complexity. The Flash version was MANY times that and has a LOT less code.
>> 
>> This turned into somewhat of an obsession for me, but I’m pleased with the results. :-)
>> 
>> HTH,
>> Harbs
>>> On Dec 16, 2021, at 8:54 PM, Harbs <harbs.lists@gmail.com <ma...@gmail.com>> wrote:
>>> 
>>> Well I spent more time. Besides the XML issues which are pretty much resolved, I ran into:
>>> 
>>> 1. I have a setter in a class which was removed by the goog dead code removal. I worked around it by turning the setter into a method. I’ll see if I can come up with a minimal test case on that.
>>> 
>>> 2. I have a library which has a LOT of dynamic pieces. I spent a LONG time trying to assign types to places where I was getting runtime errors. I now got to the point where there’s no more runtime errors, but it’s still not working and I’m pretty sure it’s because I missed some typing.
>>> 
>>> Is there any way to keep public accessors on one library or specific classes? I’d like to compile my app with:
>>> 
>>> "-js-dynamic-access-unknown-members=true",
>>> "-export-public-symbols=false",
>>> "-prevent-rename-protected-symbols=false",
>>> "-prevent-rename-public-symbols=false",
>>> "-prevent-rename-internal-symbols=false"
>>> 
>>> but be able to exclude a list of classes from that.
>>> 
>>>> On Dec 1, 2021, at 7:47 PM, Harbs <harbs.lists@gmail.com <ma...@gmail.com> <mailto:harbs.lists@gmail.com <ma...@gmail.com>>> wrote:
>>>> 
>>>> I’m pretty sure the issue is related to events not being properly handled. Although blinding might be worth looking into.
>>>> 
>>>> I’ll look into it some more when I have more time.
>>>> 
>>>> Thanks!
>>>> 
>>>>> On Dec 1, 2021, at 7:14 PM, Josh Tynjala <joshtynjala@bowlerhat.dev <ma...@bowlerhat.dev> <mailto:joshtynjala@bowlerhat.dev <ma...@bowlerhat.dev>>> wrote:
>>>>> 
>>>>>> It *almost* works. I found and fixed two cases of bracket access which
>>>>> broke things. Now I’m getting no errors, but it’s still not quite working.
>>>>> I’m guessing it’s something simple that I need to fix.
>>>>> 
>>>>> Have you tried a smaller set of prevent-rename options? That might help you
>>>>> narrow things down, if things start working better. I'd try allowing public
>>>>> variables, and maybe public accessors, to be renamed first, and see if that
>>>>> works. Those types of symbols are most likely to be getting accessed
>>>>> dynamically somehow. However, I don't really have much in the way of tips
>>>>> to narrow it down from there. ConstantBinding would be one thing to look
>>>>> out for, which I mentioned in my summary.
> 


Re: Compiler options for reducing release build size of Royale projects (Part 2)

Posted by Harbs <ha...@gmail.com>.
Let me qualify that.

If you use "-js-dynamic-access-unknown-members=true” all untyped members are quoted.

If you don’t use "-js-dynamic-access-unknown-members=true”, then the minification even without exports should work fine, but then you need to make sure you quote any Object members where the name is significant (i.e. data coming from JSON, etc.)

If you need "-js-dynamic-access-unknown-members=true”, then you will get accessor mismatches unless you consistently use data types and not “Object” or “*”. Included in that is access to Array members (i.e. myArray[i].fooBaz() is a no-no because it will get quoted on output). Neither Jewel nor MX/Spark was written with that in mind. It’s fixable, but it will take time. I fixed the general framework classes, but those component sets were not within scope for me.

HTH,
Harbs

> On Dec 29, 2021, at 8:01 AM, Yishay Weiss <yi...@hotmail.com> wrote:
> 
>> 1. Jewel does not look like it can be aggressively minified. (Spectrum can.)
>> 2. MX/Spark does not look like it can either.
> 
> Can you explain this?
> 
> 
> From: Harbs<mailto:harbs.lists@gmail.com <ma...@gmail.com>>
> Sent: Tuesday, December 28, 2021 11:36 PM
> To: Apache Royale Development<mailto:dev@royale.apache.org <ma...@royale.apache.org>>
> Subject: Re: Compiler options for reducing release build size of Royale projects (Part 2)
> 
> After 2 weeks of intense work, I got my app fully functional with the options below.
> 
> Here’s in short what I did:
> 
> 1. I audited as many cases of quoted access I could in the unminified JS code. Any place where it was accessing something on a class/instance was because the compiler couldn’t figure out the type.
> 2. I added types to all the places I could find. I basically eliminated every use of :Object and :* that I could.
> 3. I used Vectors where I could (using the -js-vector-emulation-class=Array option)
> 4. I removed unknown class accessors (no looping through classes and calling static methods)
> 5. Removed all the dynamic bracket access and assignment. (no for-ins on class instances, etc.)
> 
> In my travels I discovered that:
> 1. Jewel does not look like it can be aggressively minified. (Spectrum can.)
> 2. MX/Spark does not look like it can either.
> 3. I need to heavily modify my already modified version of TLF to get it to work with minification.
> 4. There was some unnecessary Reflection and Vector dependencies in framework code which I fixed.
> 5. Class names is a prime candidate for code removal, and (besides reflection) the current roadblock with that is SimpleCSSValuesImpl which accesses ROYALE_CLASS_INFO. If we can eliminate that, I’d save 66KB (12KB gzipped) in my app.
> 6. It’s worthwhile to use protected methods for event listener callbacks, because the long-winded private method names end up in the minified code. (I still need to address this.)
> 
> End results:
> 
> Before my effort, my app was 2,903,814 bytes and 777,071 bytes when gzipped
> Afterwards: 1,989,596 bytes and 621,851 bytes gzipped
> 
> That’s a savings of 1MB before gzipping (about 1/3) and 155KB after gzipping. (about 20% reduction)
> 
> If we can get rid of the class names we can get down to: 1,923,653 bytes/610,493 bytes.
> 
> A little over 600KB is a totally reasonable size for an application of this size and complexity. The Flash version was MANY times that and has a LOT less code.
> 
> This turned into somewhat of an obsession for me, but I’m pleased with the results. :-)
> 
> HTH,
> Harbs
>> On Dec 16, 2021, at 8:54 PM, Harbs <ha...@gmail.com> wrote:
>> 
>> Well I spent more time. Besides the XML issues which are pretty much resolved, I ran into:
>> 
>> 1. I have a setter in a class which was removed by the goog dead code removal. I worked around it by turning the setter into a method. I’ll see if I can come up with a minimal test case on that.
>> 
>> 2. I have a library which has a LOT of dynamic pieces. I spent a LONG time trying to assign types to places where I was getting runtime errors. I now got to the point where there’s no more runtime errors, but it’s still not working and I’m pretty sure it’s because I missed some typing.
>> 
>> Is there any way to keep public accessors on one library or specific classes? I’d like to compile my app with:
>> 
>> "-js-dynamic-access-unknown-members=true",
>> "-export-public-symbols=false",
>> "-prevent-rename-protected-symbols=false",
>> "-prevent-rename-public-symbols=false",
>> "-prevent-rename-internal-symbols=false"
>> 
>> but be able to exclude a list of classes from that.
>> 
>>> On Dec 1, 2021, at 7:47 PM, Harbs <harbs.lists@gmail.com <ma...@gmail.com> <mailto:harbs.lists@gmail.com <ma...@gmail.com>>> wrote:
>>> 
>>> I’m pretty sure the issue is related to events not being properly handled. Although blinding might be worth looking into.
>>> 
>>> I’ll look into it some more when I have more time.
>>> 
>>> Thanks!
>>> 
>>>> On Dec 1, 2021, at 7:14 PM, Josh Tynjala <joshtynjala@bowlerhat.dev <ma...@bowlerhat.dev> <mailto:joshtynjala@bowlerhat.dev <ma...@bowlerhat.dev>>> wrote:
>>>> 
>>>>> It *almost* works. I found and fixed two cases of bracket access which
>>>> broke things. Now I’m getting no errors, but it’s still not quite working.
>>>> I’m guessing it’s something simple that I need to fix.
>>>> 
>>>> Have you tried a smaller set of prevent-rename options? That might help you
>>>> narrow things down, if things start working better. I'd try allowing public
>>>> variables, and maybe public accessors, to be renamed first, and see if that
>>>> works. Those types of symbols are most likely to be getting accessed
>>>> dynamically somehow. However, I don't really have much in the way of tips
>>>> to narrow it down from there. ConstantBinding would be one thing to look
>>>> out for, which I mentioned in my summary.


RE: Compiler options for reducing release build size of Royale projects (Part 2)

Posted by Yishay Weiss <yi...@hotmail.com>.
>1. Jewel does not look like it can be aggressively minified. (Spectrum can.)
> 2. MX/Spark does not look like it can either.

Can you explain this?


From: Harbs<ma...@gmail.com>
Sent: Tuesday, December 28, 2021 11:36 PM
To: Apache Royale Development<ma...@royale.apache.org>
Subject: Re: Compiler options for reducing release build size of Royale projects (Part 2)

After 2 weeks of intense work, I got my app fully functional with the options below.

Here’s in short what I did:

1. I audited as many cases of quoted access I could in the unminified JS code. Any place where it was accessing something on a class/instance was because the compiler couldn’t figure out the type.
2. I added types to all the places I could find. I basically eliminated every use of :Object and :* that I could.
3. I used Vectors where I could (using the -js-vector-emulation-class=Array option)
4. I removed unknown class accessors (no looping through classes and calling static methods)
5. Removed all the dynamic bracket access and assignment. (no for-ins on class instances, etc.)

In my travels I discovered that:
1. Jewel does not look like it can be aggressively minified. (Spectrum can.)
2. MX/Spark does not look like it can either.
3. I need to heavily modify my already modified version of TLF to get it to work with minification.
4. There was some unnecessary Reflection and Vector dependencies in framework code which I fixed.
5. Class names is a prime candidate for code removal, and (besides reflection) the current roadblock with that is SimpleCSSValuesImpl which accesses ROYALE_CLASS_INFO. If we can eliminate that, I’d save 66KB (12KB gzipped) in my app.
6. It’s worthwhile to use protected methods for event listener callbacks, because the long-winded private method names end up in the minified code. (I still need to address this.)

End results:

Before my effort, my app was 2,903,814 bytes and 777,071 bytes when gzipped
Afterwards: 1,989,596 bytes and 621,851 bytes gzipped

That’s a savings of 1MB before gzipping (about 1/3) and 155KB after gzipping. (about 20% reduction)

If we can get rid of the class names we can get down to: 1,923,653 bytes/610,493 bytes.

A little over 600KB is a totally reasonable size for an application of this size and complexity. The Flash version was MANY times that and has a LOT less code.

This turned into somewhat of an obsession for me, but I’m pleased with the results. :-)

HTH,
Harbs
> On Dec 16, 2021, at 8:54 PM, Harbs <ha...@gmail.com> wrote:
>
> Well I spent more time. Besides the XML issues which are pretty much resolved, I ran into:
>
> 1. I have a setter in a class which was removed by the goog dead code removal. I worked around it by turning the setter into a method. I’ll see if I can come up with a minimal test case on that.
>
> 2. I have a library which has a LOT of dynamic pieces. I spent a LONG time trying to assign types to places where I was getting runtime errors. I now got to the point where there’s no more runtime errors, but it’s still not working and I’m pretty sure it’s because I missed some typing.
>
> Is there any way to keep public accessors on one library or specific classes? I’d like to compile my app with:
>
> "-js-dynamic-access-unknown-members=true",
> "-export-public-symbols=false",
> "-prevent-rename-protected-symbols=false",
> "-prevent-rename-public-symbols=false",
> "-prevent-rename-internal-symbols=false"
>
> but be able to exclude a list of classes from that.
>
>> On Dec 1, 2021, at 7:47 PM, Harbs <harbs.lists@gmail.com <ma...@gmail.com>> wrote:
>>
>> I’m pretty sure the issue is related to events not being properly handled. Although blinding might be worth looking into.
>>
>> I’ll look into it some more when I have more time.
>>
>> Thanks!
>>
>>> On Dec 1, 2021, at 7:14 PM, Josh Tynjala <joshtynjala@bowlerhat.dev <ma...@bowlerhat.dev>> wrote:
>>>
>>>> It *almost* works. I found and fixed two cases of bracket access which
>>> broke things. Now I’m getting no errors, but it’s still not quite working.
>>> I’m guessing it’s something simple that I need to fix.
>>>
>>> Have you tried a smaller set of prevent-rename options? That might help you
>>> narrow things down, if things start working better. I'd try allowing public
>>> variables, and maybe public accessors, to be renamed first, and see if that
>>> works. Those types of symbols are most likely to be getting accessed
>>> dynamically somehow. However, I don't really have much in the way of tips
>>> to narrow it down from there. ConstantBinding would be one thing to look
>>> out for, which I mentioned in my summary.
>>
>


Re: Compiler options for reducing release build size of Royale projects (Part 2)

Posted by Harbs <ha...@gmail.com>.
I put my thoughts together on improving SimpleCSSValuesImpl here: https://github.com/apache/royale-asjs/issues/1171

Regarding your points:

> On Dec 29, 2021, at 3:55 AM, Alex Harui <ah...@adobe.com.INVALID> wrote:
> 
> Theoretically, we can build a better optimizer/minifier than Google since they have to be general purpose and we know the patterns in our code.

Yeah. Maybe one day. This sounds like a super-hard problem.

> I've mentioned adding a super-strict compiler option before.  It would warn on every Object and * type resolution.  Maybe that would help?

Probably not. I have too many legitimate cases of those.

> Does it matter whether you remove unused classname strings before or after minification?  Maybe a post-processor can remove all className strings that aren't implementing IUIBase if you know you don't need them.

No. I actually have a post-processor shell script to get rid of (actually rename) qualified names. But we should have a general purpose solution

> We discussed ways of shortening private names in the past as well.  Maybe it is time to implement that.

Maybe.

> 
> -Alex
> 
> On 12/28/21, 1:36 PM, "Harbs" <harbs.lists@gmail.com <ma...@gmail.com>> wrote:
> 
>    After 2 weeks of intense work, I got my app fully functional with the options below.
> 
>    Here’s in short what I did:
> 
>    1. I audited as many cases of quoted access I could in the unminified JS code. Any place where it was accessing something on a class/instance was because the compiler couldn’t figure out the type.
>    2. I added types to all the places I could find. I basically eliminated every use of :Object and :* that I could.
>    3. I used Vectors where I could (using the -js-vector-emulation-class=Array option)
>    4. I removed unknown class accessors (no looping through classes and calling static methods) 
>    5. Removed all the dynamic bracket access and assignment. (no for-ins on class instances, etc.)
> 
>    In my travels I discovered that:
>    1. Jewel does not look like it can be aggressively minified. (Spectrum can.)
>    2. MX/Spark does not look like it can either.
>    3. I need to heavily modify my already modified version of TLF to get it to work with minification.
>    4. There was some unnecessary Reflection and Vector dependencies in framework code which I fixed.
>    5. Class names is a prime candidate for code removal, and (besides reflection) the current roadblock with that is SimpleCSSValuesImpl which accesses ROYALE_CLASS_INFO. If we can eliminate that, I’d save 66KB (12KB gzipped) in my app.
>    6. It’s worthwhile to use protected methods for event listener callbacks, because the long-winded private method names end up in the minified code. (I still need to address this.)
> 
>    End results:
> 
>    Before my effort, my app was 2,903,814 bytes and 777,071 bytes when gzipped
>    Afterwards: 1,989,596 bytes and 621,851 bytes gzipped
> 
>    That’s a savings of 1MB before gzipping (about 1/3) and 155KB after gzipping. (about 20% reduction)
> 
>    If we can get rid of the class names we can get down to: 1,923,653 bytes/610,493 bytes.
> 
>    A little over 600KB is a totally reasonable size for an application of this size and complexity. The Flash version was MANY times that and has a LOT less code.
> 
>    This turned into somewhat of an obsession for me, but I’m pleased with the results. :-)
> 
>    HTH,
>    Harbs
>> On Dec 16, 2021, at 8:54 PM, Harbs <ha...@gmail.com> wrote:
>> 
>> Well I spent more time. Besides the XML issues which are pretty much resolved, I ran into:
>> 
>> 1. I have a setter in a class which was removed by the goog dead code removal. I worked around it by turning the setter into a method. I’ll see if I can come up with a minimal test case on that.
>> 
>> 2. I have a library which has a LOT of dynamic pieces. I spent a LONG time trying to assign types to places where I was getting runtime errors. I now got to the point where there’s no more runtime errors, but it’s still not working and I’m pretty sure it’s because I missed some typing.
>> 
>> Is there any way to keep public accessors on one library or specific classes? I’d like to compile my app with:
>> 
>> "-js-dynamic-access-unknown-members=true",
>> "-export-public-symbols=false",
>> "-prevent-rename-protected-symbols=false",
>> "-prevent-rename-public-symbols=false",
>> "-prevent-rename-internal-symbols=false"
>> 
>> but be able to exclude a list of classes from that.
>> 
>>> On Dec 1, 2021, at 7:47 PM, Harbs <harbs.lists@gmail.com <ma...@gmail.com> <mailto:harbs.lists@gmail.com <ma...@gmail.com>>> wrote:
>>> 
>>> I’m pretty sure the issue is related to events not being properly handled. Although blinding might be worth looking into.
>>> 
>>> I’ll look into it some more when I have more time.
>>> 
>>> Thanks!
>>> 
>>>> On Dec 1, 2021, at 7:14 PM, Josh Tynjala <joshtynjala@bowlerhat.dev <ma...@bowlerhat.dev> <mailto:joshtynjala@bowlerhat.dev <ma...@bowlerhat.dev>>> wrote:
>>>> 
>>>>> It *almost* works. I found and fixed two cases of bracket access which
>>>> broke things. Now I’m getting no errors, but it’s still not quite working.
>>>> I’m guessing it’s something simple that I need to fix.
>>>> 
>>>> Have you tried a smaller set of prevent-rename options? That might help you
>>>> narrow things down, if things start working better. I'd try allowing public
>>>> variables, and maybe public accessors, to be renamed first, and see if that
>>>> works. Those types of symbols are most likely to be getting accessed
>>>> dynamically somehow. However, I don't really have much in the way of tips
>>>> to narrow it down from there. ConstantBinding would be one thing to look
>>>> out for, which I mentioned in my summary.


Re: Compiler options for reducing release build size of Royale projects (Part 2)

Posted by Alex Harui <ah...@adobe.com.INVALID>.
Theoretically, we can build a better optimizer/minifier than Google since they have to be general purpose and we know the patterns in our code.

I've mentioned adding a super-strict compiler option before.  It would warn on every Object and * type resolution.  Maybe that would help?

Does it matter whether you remove unused classname strings before or after minification?  Maybe a post-processor can remove all className strings that aren't implementing IUIBase if you know you don't need them.

We discussed ways of shortening private names in the past as well.  Maybe it is time to implement that.

-Alex

On 12/28/21, 1:36 PM, "Harbs" <ha...@gmail.com> wrote:

    After 2 weeks of intense work, I got my app fully functional with the options below.

    Here’s in short what I did:

    1. I audited as many cases of quoted access I could in the unminified JS code. Any place where it was accessing something on a class/instance was because the compiler couldn’t figure out the type.
    2. I added types to all the places I could find. I basically eliminated every use of :Object and :* that I could.
    3. I used Vectors where I could (using the -js-vector-emulation-class=Array option)
    4. I removed unknown class accessors (no looping through classes and calling static methods) 
    5. Removed all the dynamic bracket access and assignment. (no for-ins on class instances, etc.)

    In my travels I discovered that:
    1. Jewel does not look like it can be aggressively minified. (Spectrum can.)
    2. MX/Spark does not look like it can either.
    3. I need to heavily modify my already modified version of TLF to get it to work with minification.
    4. There was some unnecessary Reflection and Vector dependencies in framework code which I fixed.
    5. Class names is a prime candidate for code removal, and (besides reflection) the current roadblock with that is SimpleCSSValuesImpl which accesses ROYALE_CLASS_INFO. If we can eliminate that, I’d save 66KB (12KB gzipped) in my app.
    6. It’s worthwhile to use protected methods for event listener callbacks, because the long-winded private method names end up in the minified code. (I still need to address this.)

    End results:

    Before my effort, my app was 2,903,814 bytes and 777,071 bytes when gzipped
    Afterwards: 1,989,596 bytes and 621,851 bytes gzipped

    That’s a savings of 1MB before gzipping (about 1/3) and 155KB after gzipping. (about 20% reduction)

    If we can get rid of the class names we can get down to: 1,923,653 bytes/610,493 bytes.

    A little over 600KB is a totally reasonable size for an application of this size and complexity. The Flash version was MANY times that and has a LOT less code.

    This turned into somewhat of an obsession for me, but I’m pleased with the results. :-)

    HTH,
    Harbs
    > On Dec 16, 2021, at 8:54 PM, Harbs <ha...@gmail.com> wrote:
    > 
    > Well I spent more time. Besides the XML issues which are pretty much resolved, I ran into:
    > 
    > 1. I have a setter in a class which was removed by the goog dead code removal. I worked around it by turning the setter into a method. I’ll see if I can come up with a minimal test case on that.
    > 
    > 2. I have a library which has a LOT of dynamic pieces. I spent a LONG time trying to assign types to places where I was getting runtime errors. I now got to the point where there’s no more runtime errors, but it’s still not working and I’m pretty sure it’s because I missed some typing.
    > 
    > Is there any way to keep public accessors on one library or specific classes? I’d like to compile my app with:
    > 
    > "-js-dynamic-access-unknown-members=true",
    > "-export-public-symbols=false",
    > "-prevent-rename-protected-symbols=false",
    > "-prevent-rename-public-symbols=false",
    > "-prevent-rename-internal-symbols=false"
    > 
    > but be able to exclude a list of classes from that.
    > 
    >> On Dec 1, 2021, at 7:47 PM, Harbs <harbs.lists@gmail.com <ma...@gmail.com>> wrote:
    >> 
    >> I’m pretty sure the issue is related to events not being properly handled. Although blinding might be worth looking into.
    >> 
    >> I’ll look into it some more when I have more time.
    >> 
    >> Thanks!
    >> 
    >>> On Dec 1, 2021, at 7:14 PM, Josh Tynjala <joshtynjala@bowlerhat.dev <ma...@bowlerhat.dev>> wrote:
    >>> 
    >>>> It *almost* works. I found and fixed two cases of bracket access which
    >>> broke things. Now I’m getting no errors, but it’s still not quite working.
    >>> I’m guessing it’s something simple that I need to fix.
    >>> 
    >>> Have you tried a smaller set of prevent-rename options? That might help you
    >>> narrow things down, if things start working better. I'd try allowing public
    >>> variables, and maybe public accessors, to be renamed first, and see if that
    >>> works. Those types of symbols are most likely to be getting accessed
    >>> dynamically somehow. However, I don't really have much in the way of tips
    >>> to narrow it down from there. ConstantBinding would be one thing to look
    >>> out for, which I mentioned in my summary.
    >> 
    > 



Re: Compiler options for reducing release build size of Royale projects (Part 2)

Posted by Harbs <ha...@gmail.com>.
After 2 weeks of intense work, I got my app fully functional with the options below.

Here’s in short what I did:

1. I audited as many cases of quoted access I could in the unminified JS code. Any place where it was accessing something on a class/instance was because the compiler couldn’t figure out the type.
2. I added types to all the places I could find. I basically eliminated every use of :Object and :* that I could.
3. I used Vectors where I could (using the -js-vector-emulation-class=Array option)
4. I removed unknown class accessors (no looping through classes and calling static methods) 
5. Removed all the dynamic bracket access and assignment. (no for-ins on class instances, etc.)

In my travels I discovered that:
1. Jewel does not look like it can be aggressively minified. (Spectrum can.)
2. MX/Spark does not look like it can either.
3. I need to heavily modify my already modified version of TLF to get it to work with minification.
4. There was some unnecessary Reflection and Vector dependencies in framework code which I fixed.
5. Class names is a prime candidate for code removal, and (besides reflection) the current roadblock with that is SimpleCSSValuesImpl which accesses ROYALE_CLASS_INFO. If we can eliminate that, I’d save 66KB (12KB gzipped) in my app.
6. It’s worthwhile to use protected methods for event listener callbacks, because the long-winded private method names end up in the minified code. (I still need to address this.)

End results:

Before my effort, my app was 2,903,814 bytes and 777,071 bytes when gzipped
Afterwards: 1,989,596 bytes and 621,851 bytes gzipped

That’s a savings of 1MB before gzipping (about 1/3) and 155KB after gzipping. (about 20% reduction)

If we can get rid of the class names we can get down to: 1,923,653 bytes/610,493 bytes.

A little over 600KB is a totally reasonable size for an application of this size and complexity. The Flash version was MANY times that and has a LOT less code.

This turned into somewhat of an obsession for me, but I’m pleased with the results. :-)

HTH,
Harbs
> On Dec 16, 2021, at 8:54 PM, Harbs <ha...@gmail.com> wrote:
> 
> Well I spent more time. Besides the XML issues which are pretty much resolved, I ran into:
> 
> 1. I have a setter in a class which was removed by the goog dead code removal. I worked around it by turning the setter into a method. I’ll see if I can come up with a minimal test case on that.
> 
> 2. I have a library which has a LOT of dynamic pieces. I spent a LONG time trying to assign types to places where I was getting runtime errors. I now got to the point where there’s no more runtime errors, but it’s still not working and I’m pretty sure it’s because I missed some typing.
> 
> Is there any way to keep public accessors on one library or specific classes? I’d like to compile my app with:
> 
> "-js-dynamic-access-unknown-members=true",
> "-export-public-symbols=false",
> "-prevent-rename-protected-symbols=false",
> "-prevent-rename-public-symbols=false",
> "-prevent-rename-internal-symbols=false"
> 
> but be able to exclude a list of classes from that.
> 
>> On Dec 1, 2021, at 7:47 PM, Harbs <harbs.lists@gmail.com <ma...@gmail.com>> wrote:
>> 
>> I’m pretty sure the issue is related to events not being properly handled. Although blinding might be worth looking into.
>> 
>> I’ll look into it some more when I have more time.
>> 
>> Thanks!
>> 
>>> On Dec 1, 2021, at 7:14 PM, Josh Tynjala <joshtynjala@bowlerhat.dev <ma...@bowlerhat.dev>> wrote:
>>> 
>>>> It *almost* works. I found and fixed two cases of bracket access which
>>> broke things. Now I’m getting no errors, but it’s still not quite working.
>>> I’m guessing it’s something simple that I need to fix.
>>> 
>>> Have you tried a smaller set of prevent-rename options? That might help you
>>> narrow things down, if things start working better. I'd try allowing public
>>> variables, and maybe public accessors, to be renamed first, and see if that
>>> works. Those types of symbols are most likely to be getting accessed
>>> dynamically somehow. However, I don't really have much in the way of tips
>>> to narrow it down from there. ConstantBinding would be one thing to look
>>> out for, which I mentioned in my summary.
>> 
> 


Re: Compiler options for reducing release build size of Royale projects (Part 2)

Posted by Josh Tynjala <jo...@bowlerhat.dev>.
I would think not, since they need to keep their correct name to work
properly with the built-in behavior of JS.

--
Josh Tynjala
Bowler Hat LLC <https://bowlerhat.dev>


On Wed, Dec 22, 2021 at 4:17 AM Harbs <ha...@gmail.com> wrote:

> A question came to mind as I’m working on this:
>
> Can I assume that toString and valueOf do not get renamed when minified?
> (I assume that it doesn’t get renamed.)

Re: Compiler options for reducing release build size of Royale projects (Part 2)

Posted by Harbs <ha...@gmail.com>.
A question came to mind as I’m working on this:

Can I assume that toString and valueOf do not get renamed when minified? (I assume that it doesn’t get renamed.)

Re: Compiler options for reducing release build size of Royale projects (Part 2)

Posted by Harbs <ha...@gmail.com>.
Separate issue.

> On Dec 20, 2021, at 7:05 PM, Josh Tynjala <jo...@bowlerhat.dev> wrote:
> 
>> I have a setter in a class which was removed by the goog dead code
> removal. I worked around it by turning the setter into a method. I’ll see
> if I can come up with a minimal test case on that.
> 
> Was this related to your IHasLabelField interface changes? Or is it
> a separate issue?
> 
> --
> Josh Tynjala
> Bowler Hat LLC <https://bowlerhat.dev <https://bowlerhat.dev/>>
> 
> 
> On Thu, Dec 16, 2021 at 10:54 AM Harbs <harbs.lists@gmail.com <ma...@gmail.com>> wrote:
> 
>> Well I spent more time. Besides the XML issues which are pretty much
>> resolved, I ran into:
>> 
>> 1. I have a setter in a class which was removed by the goog dead code
>> removal. I worked around it by turning the setter into a method. I’ll see
>> if I can come up with a minimal test case on that.
>> 
>> 2. I have a library which has a LOT of dynamic pieces. I spent a LONG time
>> trying to assign types to places where I was getting runtime errors. I now
>> got to the point where there’s no more runtime errors, but it’s still not
>> working and I’m pretty sure it’s because I missed some typing.
>> 
>> Is there any way to keep public accessors on one library or specific
>> classes? I’d like to compile my app with:
>> 
>> "-js-dynamic-access-unknown-members=true",
>> "-export-public-symbols=false",
>> "-prevent-rename-protected-symbols=false",
>> "-prevent-rename-public-symbols=false",
>> "-prevent-rename-internal-symbols=false"
>> 
>> but be able to exclude a list of classes from that.
>> 
>>> On Dec 1, 2021, at 7:47 PM, Harbs <ha...@gmail.com> wrote:
>>> 
>>> I’m pretty sure the issue is related to events not being properly
>> handled. Although blinding might be worth looking into.
>>> 
>>> I’ll look into it some more when I have more time.
>>> 
>>> Thanks!
>>> 
>>>> On Dec 1, 2021, at 7:14 PM, Josh Tynjala <joshtynjala@bowlerhat.dev
>> <mailto:joshtynjala@bowlerhat.dev <ma...@bowlerhat.dev>>> wrote:
>>>> 
>>>>> It *almost* works. I found and fixed two cases of bracket access which
>>>> broke things. Now I’m getting no errors, but it’s still not quite
>> working.
>>>> I’m guessing it’s something simple that I need to fix.
>>>> 
>>>> Have you tried a smaller set of prevent-rename options? That might help
>> you
>>>> narrow things down, if things start working better. I'd try allowing
>> public
>>>> variables, and maybe public accessors, to be renamed first, and see if
>> that
>>>> works. Those types of symbols are most likely to be getting accessed
>>>> dynamically somehow. However, I don't really have much in the way of
>> tips
>>>> to narrow it down from there. ConstantBinding would be one thing to look
>>>> out for, which I mentioned in my summary.


Re: Compiler options for reducing release build size of Royale projects (Part 2)

Posted by Josh Tynjala <jo...@bowlerhat.dev>.
> I have a setter in a class which was removed by the goog dead code
removal. I worked around it by turning the setter into a method. I’ll see
if I can come up with a minimal test case on that.

Was this related to your IHasLabelField interface changes? Or is it
a separate issue?

--
Josh Tynjala
Bowler Hat LLC <https://bowlerhat.dev>


On Thu, Dec 16, 2021 at 10:54 AM Harbs <ha...@gmail.com> wrote:

> Well I spent more time. Besides the XML issues which are pretty much
> resolved, I ran into:
>
> 1. I have a setter in a class which was removed by the goog dead code
> removal. I worked around it by turning the setter into a method. I’ll see
> if I can come up with a minimal test case on that.
>
> 2. I have a library which has a LOT of dynamic pieces. I spent a LONG time
> trying to assign types to places where I was getting runtime errors. I now
> got to the point where there’s no more runtime errors, but it’s still not
> working and I’m pretty sure it’s because I missed some typing.
>
> Is there any way to keep public accessors on one library or specific
> classes? I’d like to compile my app with:
>
> "-js-dynamic-access-unknown-members=true",
> "-export-public-symbols=false",
> "-prevent-rename-protected-symbols=false",
> "-prevent-rename-public-symbols=false",
> "-prevent-rename-internal-symbols=false"
>
> but be able to exclude a list of classes from that.
>
> > On Dec 1, 2021, at 7:47 PM, Harbs <ha...@gmail.com> wrote:
> >
> > I’m pretty sure the issue is related to events not being properly
> handled. Although blinding might be worth looking into.
> >
> > I’ll look into it some more when I have more time.
> >
> > Thanks!
> >
> >> On Dec 1, 2021, at 7:14 PM, Josh Tynjala <joshtynjala@bowlerhat.dev
> <ma...@bowlerhat.dev>> wrote:
> >>
> >>> It *almost* works. I found and fixed two cases of bracket access which
> >> broke things. Now I’m getting no errors, but it’s still not quite
> working.
> >> I’m guessing it’s something simple that I need to fix.
> >>
> >> Have you tried a smaller set of prevent-rename options? That might help
> you
> >> narrow things down, if things start working better. I'd try allowing
> public
> >> variables, and maybe public accessors, to be renamed first, and see if
> that
> >> works. Those types of symbols are most likely to be getting accessed
> >> dynamically somehow. However, I don't really have much in the way of
> tips
> >> to narrow it down from there. ConstantBinding would be one thing to look
> >> out for, which I mentioned in my summary.
> >
>
>

RE: Compiler options for reducing release build size of Royale projects (Part 2)

Posted by Maria Jose Esteve <mj...@iest.com>.
Harb, what do you mean by "trying to assign types to places"? I will have to do the same

Hiedra

-----Mensaje original-----
De: Harbs <ha...@gmail.com> 
Enviado el: jueves, 16 de diciembre de 2021 19:55
Para: Apache Royale Development <de...@royale.apache.org>
Asunto: Re: Compiler options for reducing release build size of Royale projects (Part 2)

Well I spent more time. Besides the XML issues which are pretty much resolved, I ran into:

1. I have a setter in a class which was removed by the goog dead code removal. I worked around it by turning the setter into a method. I’ll see if I can come up with a minimal test case on that.

2. I have a library which has a LOT of dynamic pieces. I spent a LONG time trying to assign types to places where I was getting runtime errors. I now got to the point where there’s no more runtime errors, but it’s still not working and I’m pretty sure it’s because I missed some typing.

Is there any way to keep public accessors on one library or specific classes? I’d like to compile my app with:

"-js-dynamic-access-unknown-members=true",
"-export-public-symbols=false",
"-prevent-rename-protected-symbols=false",
"-prevent-rename-public-symbols=false",
"-prevent-rename-internal-symbols=false"

but be able to exclude a list of classes from that.

> On Dec 1, 2021, at 7:47 PM, Harbs <ha...@gmail.com> wrote:
> 
> I’m pretty sure the issue is related to events not being properly handled. Although blinding might be worth looking into.
> 
> I’ll look into it some more when I have more time.
> 
> Thanks!
> 
>> On Dec 1, 2021, at 7:14 PM, Josh Tynjala <joshtynjala@bowlerhat.dev <ma...@bowlerhat.dev>> wrote:
>> 
>>> It *almost* works. I found and fixed two cases of bracket access 
>>> which
>> broke things. Now I’m getting no errors, but it’s still not quite working.
>> I’m guessing it’s something simple that I need to fix.
>> 
>> Have you tried a smaller set of prevent-rename options? That might 
>> help you narrow things down, if things start working better. I'd try 
>> allowing public variables, and maybe public accessors, to be renamed 
>> first, and see if that works. Those types of symbols are most likely 
>> to be getting accessed dynamically somehow. However, I don't really 
>> have much in the way of tips to narrow it down from there. 
>> ConstantBinding would be one thing to look out for, which I mentioned in my summary.
> 


Re: Compiler options for reducing release build size of Royale projects (Part 2)

Posted by Josh Tynjala <jo...@bowlerhat.dev>.
There is currently no way to exclude a library or a list of classes from
being affected by these compiler options.

--
Josh Tynjala
Bowler Hat LLC <https://bowlerhat.dev>


On Thu, Dec 16, 2021 at 10:54 AM Harbs <ha...@gmail.com> wrote:

> Well I spent more time. Besides the XML issues which are pretty much
> resolved, I ran into:
>
> 1. I have a setter in a class which was removed by the goog dead code
> removal. I worked around it by turning the setter into a method. I’ll see
> if I can come up with a minimal test case on that.
>
> 2. I have a library which has a LOT of dynamic pieces. I spent a LONG time
> trying to assign types to places where I was getting runtime errors. I now
> got to the point where there’s no more runtime errors, but it’s still not
> working and I’m pretty sure it’s because I missed some typing.
>
> Is there any way to keep public accessors on one library or specific
> classes? I’d like to compile my app with:
>
> "-js-dynamic-access-unknown-members=true",
> "-export-public-symbols=false",
> "-prevent-rename-protected-symbols=false",
> "-prevent-rename-public-symbols=false",
> "-prevent-rename-internal-symbols=false"
>
> but be able to exclude a list of classes from that.
>
> > On Dec 1, 2021, at 7:47 PM, Harbs <ha...@gmail.com> wrote:
> >
> > I’m pretty sure the issue is related to events not being properly
> handled. Although blinding might be worth looking into.
> >
> > I’ll look into it some more when I have more time.
> >
> > Thanks!
> >
> >> On Dec 1, 2021, at 7:14 PM, Josh Tynjala <joshtynjala@bowlerhat.dev
> <ma...@bowlerhat.dev>> wrote:
> >>
> >>> It *almost* works. I found and fixed two cases of bracket access which
> >> broke things. Now I’m getting no errors, but it’s still not quite
> working.
> >> I’m guessing it’s something simple that I need to fix.
> >>
> >> Have you tried a smaller set of prevent-rename options? That might help
> you
> >> narrow things down, if things start working better. I'd try allowing
> public
> >> variables, and maybe public accessors, to be renamed first, and see if
> that
> >> works. Those types of symbols are most likely to be getting accessed
> >> dynamically somehow. However, I don't really have much in the way of
> tips
> >> to narrow it down from there. ConstantBinding would be one thing to look
> >> out for, which I mentioned in my summary.
> >
>
>

Re: Compiler options for reducing release build size of Royale projects (Part 2)

Posted by Harbs <ha...@gmail.com>.
Well I spent more time. Besides the XML issues which are pretty much resolved, I ran into:

1. I have a setter in a class which was removed by the goog dead code removal. I worked around it by turning the setter into a method. I’ll see if I can come up with a minimal test case on that.

2. I have a library which has a LOT of dynamic pieces. I spent a LONG time trying to assign types to places where I was getting runtime errors. I now got to the point where there’s no more runtime errors, but it’s still not working and I’m pretty sure it’s because I missed some typing.

Is there any way to keep public accessors on one library or specific classes? I’d like to compile my app with:

"-js-dynamic-access-unknown-members=true",
"-export-public-symbols=false",
"-prevent-rename-protected-symbols=false",
"-prevent-rename-public-symbols=false",
"-prevent-rename-internal-symbols=false"

but be able to exclude a list of classes from that.

> On Dec 1, 2021, at 7:47 PM, Harbs <ha...@gmail.com> wrote:
> 
> I’m pretty sure the issue is related to events not being properly handled. Although blinding might be worth looking into.
> 
> I’ll look into it some more when I have more time.
> 
> Thanks!
> 
>> On Dec 1, 2021, at 7:14 PM, Josh Tynjala <joshtynjala@bowlerhat.dev <ma...@bowlerhat.dev>> wrote:
>> 
>>> It *almost* works. I found and fixed two cases of bracket access which
>> broke things. Now I’m getting no errors, but it’s still not quite working.
>> I’m guessing it’s something simple that I need to fix.
>> 
>> Have you tried a smaller set of prevent-rename options? That might help you
>> narrow things down, if things start working better. I'd try allowing public
>> variables, and maybe public accessors, to be renamed first, and see if that
>> works. Those types of symbols are most likely to be getting accessed
>> dynamically somehow. However, I don't really have much in the way of tips
>> to narrow it down from there. ConstantBinding would be one thing to look
>> out for, which I mentioned in my summary.
> 


Re: Compiler options for reducing release build size of Royale projects (Part 2)

Posted by Harbs <ha...@gmail.com>.
I’m pretty sure the issue is related to events not being properly handled. Although blinding might be worth looking into.

I’ll look into it some more when I have more time.

Thanks!

> On Dec 1, 2021, at 7:14 PM, Josh Tynjala <jo...@bowlerhat.dev> wrote:
> 
>> It *almost* works. I found and fixed two cases of bracket access which
> broke things. Now I’m getting no errors, but it’s still not quite working.
> I’m guessing it’s something simple that I need to fix.
> 
> Have you tried a smaller set of prevent-rename options? That might help you
> narrow things down, if things start working better. I'd try allowing public
> variables, and maybe public accessors, to be renamed first, and see if that
> works. Those types of symbols are most likely to be getting accessed
> dynamically somehow. However, I don't really have much in the way of tips
> to narrow it down from there. ConstantBinding would be one thing to look
> out for, which I mentioned in my summary.


Re: Compiler options for reducing release build size of Royale projects (Part 2)

Posted by Josh Tynjala <jo...@bowlerhat.dev>.
> Is there a reason this doesn’t work on compc? If I could allow renaming
in my libraries, I suspect I would save a lot more in size.

Exporting/renaming happens in release builds of applications only, so it
wouldn't make sense to allow these options on compc. However, when you
create a release build of an application, the exporting/renaming process is
also applied to all code used by the application, including the code from
any libraries that you use too. Your libraries are not being excluded from
this process.

> It *almost* works. I found and fixed two cases of bracket access which
broke things. Now I’m getting no errors, but it’s still not quite working.
I’m guessing it’s something simple that I need to fix.

Have you tried a smaller set of prevent-rename options? That might help you
narrow things down, if things start working better. I'd try allowing public
variables, and maybe public accessors, to be renamed first, and see if that
works. Those types of symbols are most likely to be getting accessed
dynamically somehow. However, I don't really have much in the way of tips
to narrow it down from there. ConstantBinding would be one thing to look
out for, which I mentioned in my summary.

> I also noticed that none of these options seem to allow class names to be
dropped. That’s a lot of baggage being carried around for no apparent
reason.

It's certainly possible that I accidentally overlooked class renaming, but
that doesn't sound right to me. I'll double-check.

--
Josh Tynjala
Bowler Hat LLC <https://bowlerhat.dev>


On Wed, Dec 1, 2021 at 6:28 AM Harbs <ha...@gmail.com> wrote:

> OK. I see that there’s fine-grained control over these. I used the
> following:
>
> -export-public-symbols=false -prevent-rename-protected-symbols=false
> -prevent-rename-public-static-methods=false
> -prevent-rename-public-instance-methods=false
> -prevent-rename-public-static-variables=false
> -prevent-rename-public-instance-variables=false
> -prevent-rename-public-instance-accessors=false
>
> and I got:
> 2MB and gzipped to 629KB
>
> It *almost* works. I found and fixed two cases of bracket access which
> broke things. Now I’m getting no errors, but it’s still not quite working.
> I’m guessing it’s something simple that I need to fix.
>
> It also looks like that SWC code needs to changes. So that’s good.
>
> This question is still puzzling me:
> > I also noticed that none of these options seem to allow class names to
> be dropped. That’s a lot of baggage being carried around for no apparent
> reason.
>
>
> > On Dec 1, 2021, at 1:56 PM, Harbs <ha...@gmail.com> wrote:
> >
> > Thanks for all this work!
> >
> > I finally got to trying this out on my huge production app.
> >
> > Here’s some stats.
> >
> > Original output before using the new options:
> > 2.9MB gzipped to 777KB
> >
> > using just -export-public-symbols=false:
> > 2.6MB gzipped to 734KB
> >
> > Now I have 4 (quite large) libraries compiled into swcs that I did not
> recompile before these options. Recompiling them using
> -export-public-symbols=false resulted in:
> > 2.6MB gzipped to 731KB
> >
> > It was surprising to me that -export-public-symbols=false made such a
> small difference on the libraries.
> >
> > I tried -prevent-rename-public-symbols=false on my project and I got:
> > 2.1MB gzipped down to 627KB
> >
> > That’s a huge reduction in size. The problem is that this doesn’t
> actually work. https://github.com/apache/royale-compiler/issues/200 <
> https://github.com/apache/royale-compiler/issues/200>
> >
> > I also noticed that -prevent-rename-public-symbols=false seems to only
> work with mxmlc (mxmljsc) and not with compc. When I tried
> -prevent-rename-public-symbols=false using compc I get an error: command
> line unknown configuration variable 'prevent-rename-public-symbols’.
> >
> > Is there a reason this doesn’t work on compc? If I could allow renaming
> in my libraries, I suspect I would save a lot more in size.
> >
> > I also noticed that none of these options seem to allow class names to
> be dropped. That’s a lot of baggage being carried around for no apparent
> reason.
> >
> > Another question is how this all effects Framework code. Since the JS is
> output when compiling the framework, is there any way to take advantage of
> these options in framework code?
> >
> > Thanks!
> > Harbs
> >
> >> On May 25, 2021, at 7:15 PM, Josh Tynjala <joshtynjala@bowlerhat.dev
> <ma...@bowlerhat.dev>> wrote:
> >>
> >> Some of my earlier changes made it safe to use public variables instead
> of
> >> getters/setters, at least with the compiler defaults. With certain
> >> combinations of compiler options, it is possible to make it unsafe
> again,
> >> though.
> >>
> >> If you decided to use -export-public-symbols=true and
> >> -prevent-rename-public-symbols=false together, for some reason (this
> >> wouldn't be common), that would make public variables unsafe to use
> again.
> >> Closure compiler would make a separate copy of the variable with that
> >> combination, which was the original issue that caused us to add the
> >> warning. A copy is not made for getters and setters, so that's why that
> >> advice became common. When you prevent renaming, Closure is forced to
> use
> >> the original variable when exporting, so there is no copy, and it's
> safe.
> >>
> >> --
> >> Josh Tynjala
> >> Bowler Hat LLC <https://bowlerhat.dev <https://bowlerhat.dev/>>
> >>
> >>
> >> On Mon, May 24, 2021 at 11:07 PM Yishay Weiss <yishayjobs@hotmail.com
> <ma...@hotmail.com>>
> >> wrote:
> >>
> >>> Hi Josh,
> >>>
> >>> I still haven’t wrapped my head around all of this but thanks for the
> >>> informative post. Does this somehow mean public vars are now always
> safe to
> >>> use as opposed to having to covert them to public methods?
> >>>
> >>> From: Josh Tynjala<mailto:joshtynjala@bowlerhat.dev <mailto:
> joshtynjala@bowlerhat.dev>>
> >>> Sent: Monday, May 24, 2021 11:32 PM
> >>> To: Apache Royale Development<mailto:dev@royale.apache.org <mailto:
> dev@royale.apache.org>>
> >>> Subject: Compiler options for reducing release build size of Royale
> >>> projects (Part 2)
> >>>
> >>> Back in November, I shared a summary of some of the work that I've been
> >>> doing on reducing the size of release builds generated by the Royale
> >>> compiler. Essentially, I've been trying to ensure that we could take
> better
> >>> advantage of Closure compiler's advanced optimizations for
> minification,
> >>> which includes removing dead code and renaming symbols so that they
> have
> >>> shorter names.
> >>>
> >>> Since then, I've made some more improvements to the Royale compiler,
> which
> >>> will allow even more optimization. I figured that it is a good time to
> >>> share my latest results.
> >>>
> >>> To fully understand the context of today's post, I recommend reviewing
> the
> >>> introduction that I wrote for my earlier post (you can stop once I
> start
> >>> talking about the results). Here's the link to the archive:
> >>>
> >>>
> >>>
> https://lists.apache.org/thread.html/rf53d200969d795a15bda5d6635b904d89fa7f6af151df5dca15ccbbb%40%3Cdev.royale.apache.org%3E
> <
> https://lists.apache.org/thread.html/rf53d200969d795a15bda5d6635b904d89fa7f6af151df5dca15ccbbb%40%3Cdev.royale.apache.org%3E
> >
> >>>
> >>> Last time, in my final set of results, some public symbols were
> allowed to
> >>> be renamed in the release build, but some were not. If I tried to
> rename
> >>> all public symbols, it would cause parts of the apps to stop working
> >>> correctly. My work since then has been finding ways to ensure that more
> >>> public symbols can be renamed safely.
> >>>
> >>> What I determined is that the way that we encode MXML data in
> JavaScript
> >>> results in a lot of dynamically setting properties using string names,
> >>> similar to `variable["propName"] = value`. Setting properties
> dynamically
> >>> is generally bad when minimizing with Closure compiler because it won't
> >>> understand that it needs to keep those properties, and it may remove
> them
> >>> as dead code (even though it's not dead code), or it may change their
> names
> >>> (while our code still uses the original names).
> >>>
> >>> Luckly, our MXML data in JS is well-structured, so it's possible to
> walk
> >>> the JS tree when creating the release build and extract names that are
> used
> >>> dynamically in MXML. Then, we can pass those names to Closure compiler
> >>> manually. Basically, we're extending the Closure compiler with an extra
> >>> analysis step that has specialized knowledge of Royale. This allows us
> to
> >>> rename more public symbols because we can exclude the ones that we know
> >>> cannot be renamed).
> >>>
> >>> I added a new compiler option, *prevent-rename-mxml-symbol-references*,
> >>> which defaults to true. You will probably never want to change this to
> >>> false, but the option is there, if anyone ever determines that it is
> needed
> >>> in some edge case.
> >>>
> >>> Okay, now to the results. I built the same four app projects as last
> time.
> >>>
> >>> I used the following commits, if anyone wants to try reproducing on
> their
> >>> own computer:
> >>>
> >>> royale-compiler: 65805281ea898b3a0225922f5956c864f810c423
> >>> royale-asjs: fab5f5444e0e9ee7f8f59e5cf1d4b1144a31025e
> >>> spectrum-royale: acf4007fa322d61e1d0ae874e4c2009f8645654c
> >>>
> >>> ==========
> >>> Baseline: royale-compiler 0.9.7
> >>> ==========
> >>>
> >>> HelloWorld: 71 KB
> >>> ASDoc: 237 KB
> >>> TourDeJewel: 1125 KB
> >>> SpectrumBrowser: 944 KB
> >>>
> >>> As with my previous post, I built all of the example projects with the
> >>> Royale 0.9.7 compiler first. However, I built them with the latest
> >>> framework code. This ensures that only the differences in the compiler
> are
> >>> being compared, and we don't have extra noise from differences in the
> >>> framework code.
> >>>
> >>> -----
> >>>
> >>> Now, let's see some results with the latest compiler.
> >>>
> >>> All results below include the +/- difference in KB and %. These values
> are
> >>> always in comparison to the baseline numbers above.
> >>>
> >>> ==========
> >>> Result 1: Latest compiler with default options
> >>> ==========
> >>>
> >>> HelloWorld: 87 KB (+16 KB / +23%)
> >>> ASDoc: 261 KB (+24 KB / +10%)
> >>> TourDeJewel: 1159 KB (+34 KB / +3%)
> >>> SpectrumBrowser: 980 KB (+36 KB / +4%)
> >>>
> >>> As with the previous post, the increase in file size here is expected.
> The
> >>> latest compiler fixes some bugs that were present in 0.9.7 that caused
> >>> certain symbols to be renamed/removed when they should not have been.
> >>>
> >>> ==========
> >>> Result 2: Disable symbol exports and allow non-public symbols to be
> renamed
> >>> ==========
> >>>
> >>> HelloWorld: 74 KB (+3 KB / +4%)
> >>> ASDoc: 226 KB (-11 KB / -5%)
> >>> TourDeJewel: 966 KB (-159 KB / -14%)
> >>> SpectrumBrowser: 897 KB (-47 KB / -5%)
> >>>
> >>> Compiler options used:
> >>> *-export-public-symbols=false*
> >>> *-prevent-rename-protected-symbols=false*
> >>> *-prevent-rename-internal-symbols=false*
> >>>
> >>> These results are consistent with a similar test from my previous
> post. I
> >>> included it to show that nothing has changed, and to have an
> intermediate
> >>> step between the default options and the full optimizations.
> >>>
> >>> ==========
> >>> Result 3: Allow public symbols to be renamed too
> >>> ==========
> >>>
> >>> HelloWorld: 66 KB (-5 KB / -7%)
> >>> ASDoc: N/A
> >>> TourDeJewel: N/A
> >>> SpectrumBrowser: 857 KB (-87 KB / -9%)
> >>>
> >>> Compiler options used:
> >>> -export-public-symbols=false
> >>> -prevent-rename-protected-symbols=false
> >>> -prevent-rename-internal-symbols=false
> >>> *-prevent-rename-public-symbols=false*
> >>>
> >>> This is a compiler option that I didn't include in the tests last time
> >>> because renaming all public symbols broke every app before. Now that
> the
> >>> Royale compiler walks the MXML data tree, it's possible to allow
> renaming
> >>> of public symbols in some apps (but not all, for reasons I will
> explain).
> >>> *This
> >>> combination of compiler options provides the largest possible file size
> >>> savings in release builds.*
> >>>
> >>> You'll notice that ASDoc and TourDeJewel are marked N/A. This is
> because
> >>> they use the ConstantBinding class, which sets up bindings dynamically.
> >>>
> >>> <js:ConstantBinding sourceID="listModel"
> sourcePropertyName="iconListData"
> >>> destinationPropertyName="dataProvider"/>
> >>>
> >>> When compiled to JS, this code basically converts to this:
> >>>
> >>> this[binding.destinationPropertyName] =
> >>> this[binding.sourceID][binding.sourcePropertyName];
> >>>
> >>> Notice the bracket access with string values. Like I explained before,
> >>> this is something that Closure compiler cannot detect.
> >>>
> >>> Technically, I could write another custom Closure compiler pass that
> looks
> >>> for ConstantBinding objects in the MXML data tree and extract the
> property
> >>> names. It wouldn't be hard, but what happens if new types of bindings
> are
> >>> added that work similarly? Do I just keep adding them to the compiler
> as
> >>> special cases? Or what if someone wants to use the compiler with a
> >>> different framework and wants to move ConstantBinding to a different
> >>> package? Do they need to modify the compiler too? It simply doesn't
> feel
> >>> clean to me. So, if you want to use the
> >>> -prevent-rename-public-symbols=false compiler option, I recommend
> avoiding
> >>> ConstantBinding. Regular bindings with curly braces {} are fully
> supported,
> >>> and they're what most people will be familiar with from Flex anyway.
> >>>
> >>> ==========
> >>> Extra Result: Allow *some* public symbols to be renamed
> >>> ==========
> >>>
> >>> ASDoc: 210 KB (-27 KB / -11%)
> >>> TourDeJewel: 927 KB (-198 KB / -18%)
> >>>
> >>> Compiler options used:
> >>> -export-public-symbols=false
> >>> -prevent-rename-protected-symbols=false
> >>> -prevent-rename-internal-symbols=false
> >>> *-prevent-rename-public-static-methods=false*
> >>> *-prevent-rename-public-instance-methods=false*
> >>>
> >>> That being said, even when using ConstantBinding or other dynamic
> features,
> >>> it may be possible to rename a subset of public symbols. Most commonly,
> >>> public methods are usually safe to rename because most people don't
> try to
> >>> call methods dynamically. This final extra test is consistent with a
> >>> similar result from my previous post.
> >>>
> >>> That was really long, so thank you for reading, if you made it to the
> end!
> >>>
> >>> --
> >>> Josh Tynjala
> >>> Bowler Hat LLC <https://bowlerhat.dev>
> >>>
> >>>
> >
>
>

Re: Compiler options for reducing release build size of Royale projects (Part 2)

Posted by Harbs <ha...@gmail.com>.
OK. I see that there’s fine-grained control over these. I used the following:

-export-public-symbols=false -prevent-rename-protected-symbols=false -prevent-rename-public-static-methods=false -prevent-rename-public-instance-methods=false -prevent-rename-public-static-variables=false -prevent-rename-public-instance-variables=false -prevent-rename-public-instance-accessors=false

and I got:
2MB and gzipped to 629KB

It *almost* works. I found and fixed two cases of bracket access which broke things. Now I’m getting no errors, but it’s still not quite working. I’m guessing it’s something simple that I need to fix.

It also looks like that SWC code needs to changes. So that’s good.

This question is still puzzling me:
> I also noticed that none of these options seem to allow class names to be dropped. That’s a lot of baggage being carried around for no apparent reason.


> On Dec 1, 2021, at 1:56 PM, Harbs <ha...@gmail.com> wrote:
> 
> Thanks for all this work!
> 
> I finally got to trying this out on my huge production app.
> 
> Here’s some stats.
> 
> Original output before using the new options:
> 2.9MB gzipped to 777KB
> 
> using just -export-public-symbols=false:
> 2.6MB gzipped to 734KB
> 
> Now I have 4 (quite large) libraries compiled into swcs that I did not recompile before these options. Recompiling them using -export-public-symbols=false resulted in:
> 2.6MB gzipped to 731KB
> 
> It was surprising to me that -export-public-symbols=false made such a small difference on the libraries.
> 
> I tried -prevent-rename-public-symbols=false on my project and I got:
> 2.1MB gzipped down to 627KB
> 
> That’s a huge reduction in size. The problem is that this doesn’t actually work. https://github.com/apache/royale-compiler/issues/200 <https://github.com/apache/royale-compiler/issues/200>
> 
> I also noticed that -prevent-rename-public-symbols=false seems to only work with mxmlc (mxmljsc) and not with compc. When I tried -prevent-rename-public-symbols=false using compc I get an error: command line unknown configuration variable 'prevent-rename-public-symbols’.
> 
> Is there a reason this doesn’t work on compc? If I could allow renaming in my libraries, I suspect I would save a lot more in size.
> 
> I also noticed that none of these options seem to allow class names to be dropped. That’s a lot of baggage being carried around for no apparent reason.
> 
> Another question is how this all effects Framework code. Since the JS is output when compiling the framework, is there any way to take advantage of these options in framework code?
> 
> Thanks!
> Harbs
> 
>> On May 25, 2021, at 7:15 PM, Josh Tynjala <joshtynjala@bowlerhat.dev <ma...@bowlerhat.dev>> wrote:
>> 
>> Some of my earlier changes made it safe to use public variables instead of
>> getters/setters, at least with the compiler defaults. With certain
>> combinations of compiler options, it is possible to make it unsafe again,
>> though.
>> 
>> If you decided to use -export-public-symbols=true and
>> -prevent-rename-public-symbols=false together, for some reason (this
>> wouldn't be common), that would make public variables unsafe to use again.
>> Closure compiler would make a separate copy of the variable with that
>> combination, which was the original issue that caused us to add the
>> warning. A copy is not made for getters and setters, so that's why that
>> advice became common. When you prevent renaming, Closure is forced to use
>> the original variable when exporting, so there is no copy, and it's safe.
>> 
>> --
>> Josh Tynjala
>> Bowler Hat LLC <https://bowlerhat.dev <https://bowlerhat.dev/>>
>> 
>> 
>> On Mon, May 24, 2021 at 11:07 PM Yishay Weiss <yishayjobs@hotmail.com <ma...@hotmail.com>>
>> wrote:
>> 
>>> Hi Josh,
>>> 
>>> I still haven’t wrapped my head around all of this but thanks for the
>>> informative post. Does this somehow mean public vars are now always safe to
>>> use as opposed to having to covert them to public methods?
>>> 
>>> From: Josh Tynjala<mailto:joshtynjala@bowlerhat.dev <ma...@bowlerhat.dev>>
>>> Sent: Monday, May 24, 2021 11:32 PM
>>> To: Apache Royale Development<mailto:dev@royale.apache.org <ma...@royale.apache.org>>
>>> Subject: Compiler options for reducing release build size of Royale
>>> projects (Part 2)
>>> 
>>> Back in November, I shared a summary of some of the work that I've been
>>> doing on reducing the size of release builds generated by the Royale
>>> compiler. Essentially, I've been trying to ensure that we could take better
>>> advantage of Closure compiler's advanced optimizations for minification,
>>> which includes removing dead code and renaming symbols so that they have
>>> shorter names.
>>> 
>>> Since then, I've made some more improvements to the Royale compiler, which
>>> will allow even more optimization. I figured that it is a good time to
>>> share my latest results.
>>> 
>>> To fully understand the context of today's post, I recommend reviewing the
>>> introduction that I wrote for my earlier post (you can stop once I start
>>> talking about the results). Here's the link to the archive:
>>> 
>>> 
>>> https://lists.apache.org/thread.html/rf53d200969d795a15bda5d6635b904d89fa7f6af151df5dca15ccbbb%40%3Cdev.royale.apache.org%3E <https://lists.apache.org/thread.html/rf53d200969d795a15bda5d6635b904d89fa7f6af151df5dca15ccbbb%40%3Cdev.royale.apache.org%3E>
>>> 
>>> Last time, in my final set of results, some public symbols were allowed to
>>> be renamed in the release build, but some were not. If I tried to rename
>>> all public symbols, it would cause parts of the apps to stop working
>>> correctly. My work since then has been finding ways to ensure that more
>>> public symbols can be renamed safely.
>>> 
>>> What I determined is that the way that we encode MXML data in JavaScript
>>> results in a lot of dynamically setting properties using string names,
>>> similar to `variable["propName"] = value`. Setting properties dynamically
>>> is generally bad when minimizing with Closure compiler because it won't
>>> understand that it needs to keep those properties, and it may remove them
>>> as dead code (even though it's not dead code), or it may change their names
>>> (while our code still uses the original names).
>>> 
>>> Luckly, our MXML data in JS is well-structured, so it's possible to walk
>>> the JS tree when creating the release build and extract names that are used
>>> dynamically in MXML. Then, we can pass those names to Closure compiler
>>> manually. Basically, we're extending the Closure compiler with an extra
>>> analysis step that has specialized knowledge of Royale. This allows us to
>>> rename more public symbols because we can exclude the ones that we know
>>> cannot be renamed).
>>> 
>>> I added a new compiler option, *prevent-rename-mxml-symbol-references*,
>>> which defaults to true. You will probably never want to change this to
>>> false, but the option is there, if anyone ever determines that it is needed
>>> in some edge case.
>>> 
>>> Okay, now to the results. I built the same four app projects as last time.
>>> 
>>> I used the following commits, if anyone wants to try reproducing on their
>>> own computer:
>>> 
>>> royale-compiler: 65805281ea898b3a0225922f5956c864f810c423
>>> royale-asjs: fab5f5444e0e9ee7f8f59e5cf1d4b1144a31025e
>>> spectrum-royale: acf4007fa322d61e1d0ae874e4c2009f8645654c
>>> 
>>> ==========
>>> Baseline: royale-compiler 0.9.7
>>> ==========
>>> 
>>> HelloWorld: 71 KB
>>> ASDoc: 237 KB
>>> TourDeJewel: 1125 KB
>>> SpectrumBrowser: 944 KB
>>> 
>>> As with my previous post, I built all of the example projects with the
>>> Royale 0.9.7 compiler first. However, I built them with the latest
>>> framework code. This ensures that only the differences in the compiler are
>>> being compared, and we don't have extra noise from differences in the
>>> framework code.
>>> 
>>> -----
>>> 
>>> Now, let's see some results with the latest compiler.
>>> 
>>> All results below include the +/- difference in KB and %. These values are
>>> always in comparison to the baseline numbers above.
>>> 
>>> ==========
>>> Result 1: Latest compiler with default options
>>> ==========
>>> 
>>> HelloWorld: 87 KB (+16 KB / +23%)
>>> ASDoc: 261 KB (+24 KB / +10%)
>>> TourDeJewel: 1159 KB (+34 KB / +3%)
>>> SpectrumBrowser: 980 KB (+36 KB / +4%)
>>> 
>>> As with the previous post, the increase in file size here is expected. The
>>> latest compiler fixes some bugs that were present in 0.9.7 that caused
>>> certain symbols to be renamed/removed when they should not have been.
>>> 
>>> ==========
>>> Result 2: Disable symbol exports and allow non-public symbols to be renamed
>>> ==========
>>> 
>>> HelloWorld: 74 KB (+3 KB / +4%)
>>> ASDoc: 226 KB (-11 KB / -5%)
>>> TourDeJewel: 966 KB (-159 KB / -14%)
>>> SpectrumBrowser: 897 KB (-47 KB / -5%)
>>> 
>>> Compiler options used:
>>> *-export-public-symbols=false*
>>> *-prevent-rename-protected-symbols=false*
>>> *-prevent-rename-internal-symbols=false*
>>> 
>>> These results are consistent with a similar test from my previous post. I
>>> included it to show that nothing has changed, and to have an intermediate
>>> step between the default options and the full optimizations.
>>> 
>>> ==========
>>> Result 3: Allow public symbols to be renamed too
>>> ==========
>>> 
>>> HelloWorld: 66 KB (-5 KB / -7%)
>>> ASDoc: N/A
>>> TourDeJewel: N/A
>>> SpectrumBrowser: 857 KB (-87 KB / -9%)
>>> 
>>> Compiler options used:
>>> -export-public-symbols=false
>>> -prevent-rename-protected-symbols=false
>>> -prevent-rename-internal-symbols=false
>>> *-prevent-rename-public-symbols=false*
>>> 
>>> This is a compiler option that I didn't include in the tests last time
>>> because renaming all public symbols broke every app before. Now that the
>>> Royale compiler walks the MXML data tree, it's possible to allow renaming
>>> of public symbols in some apps (but not all, for reasons I will explain).
>>> *This
>>> combination of compiler options provides the largest possible file size
>>> savings in release builds.*
>>> 
>>> You'll notice that ASDoc and TourDeJewel are marked N/A. This is because
>>> they use the ConstantBinding class, which sets up bindings dynamically.
>>> 
>>> <js:ConstantBinding sourceID="listModel" sourcePropertyName="iconListData"
>>> destinationPropertyName="dataProvider"/>
>>> 
>>> When compiled to JS, this code basically converts to this:
>>> 
>>> this[binding.destinationPropertyName] =
>>> this[binding.sourceID][binding.sourcePropertyName];
>>> 
>>> Notice the bracket access with string values. Like I explained before,
>>> this is something that Closure compiler cannot detect.
>>> 
>>> Technically, I could write another custom Closure compiler pass that looks
>>> for ConstantBinding objects in the MXML data tree and extract the property
>>> names. It wouldn't be hard, but what happens if new types of bindings are
>>> added that work similarly? Do I just keep adding them to the compiler as
>>> special cases? Or what if someone wants to use the compiler with a
>>> different framework and wants to move ConstantBinding to a different
>>> package? Do they need to modify the compiler too? It simply doesn't feel
>>> clean to me. So, if you want to use the
>>> -prevent-rename-public-symbols=false compiler option, I recommend avoiding
>>> ConstantBinding. Regular bindings with curly braces {} are fully supported,
>>> and they're what most people will be familiar with from Flex anyway.
>>> 
>>> ==========
>>> Extra Result: Allow *some* public symbols to be renamed
>>> ==========
>>> 
>>> ASDoc: 210 KB (-27 KB / -11%)
>>> TourDeJewel: 927 KB (-198 KB / -18%)
>>> 
>>> Compiler options used:
>>> -export-public-symbols=false
>>> -prevent-rename-protected-symbols=false
>>> -prevent-rename-internal-symbols=false
>>> *-prevent-rename-public-static-methods=false*
>>> *-prevent-rename-public-instance-methods=false*
>>> 
>>> That being said, even when using ConstantBinding or other dynamic features,
>>> it may be possible to rename a subset of public symbols. Most commonly,
>>> public methods are usually safe to rename because most people don't try to
>>> call methods dynamically. This final extra test is consistent with a
>>> similar result from my previous post.
>>> 
>>> That was really long, so thank you for reading, if you made it to the end!
>>> 
>>> --
>>> Josh Tynjala
>>> Bowler Hat LLC <https://bowlerhat.dev>
>>> 
>>> 
> 


Re: Compiler options for reducing release build size of Royale projects (Part 2)

Posted by Harbs <ha...@gmail.com>.
Thanks for all this work!

I finally got to trying this out on my huge production app.

Here’s some stats.

Original output before using the new options:
2.9MB gzipped to 777KB

using just -export-public-symbols=false:
2.6MB gzipped to 734KB

Now I have 4 (quite large) libraries compiled into swcs that I did not recompile before these options. Recompiling them using -export-public-symbols=false resulted in:
2.6MB gzipped to 731KB

It was surprising to me that -export-public-symbols=false made such a small difference on the libraries.

I tried -prevent-rename-public-symbols=false on my project and I got:
2.1MB gzipped down to 627KB

That’s a huge reduction in size. The problem is that this doesn’t actually work. https://github.com/apache/royale-compiler/issues/200 <https://github.com/apache/royale-compiler/issues/200>

I also noticed that -prevent-rename-public-symbols=false seems to only work with mxmlc (mxmljsc) and not with compc. When I tried -prevent-rename-public-symbols=false using compc I get an error: command line unknown configuration variable 'prevent-rename-public-symbols’.

Is there a reason this doesn’t work on compc? If I could allow renaming in my libraries, I suspect I would save a lot more in size.

I also noticed that none of these options seem to allow class names to be dropped. That’s a lot of baggage being carried around for no apparent reason.

Another question is how this all effects Framework code. Since the JS is output when compiling the framework, is there any way to take advantage of these options in framework code?

Thanks!
Harbs

> On May 25, 2021, at 7:15 PM, Josh Tynjala <jo...@bowlerhat.dev> wrote:
> 
> Some of my earlier changes made it safe to use public variables instead of
> getters/setters, at least with the compiler defaults. With certain
> combinations of compiler options, it is possible to make it unsafe again,
> though.
> 
> If you decided to use -export-public-symbols=true and
> -prevent-rename-public-symbols=false together, for some reason (this
> wouldn't be common), that would make public variables unsafe to use again.
> Closure compiler would make a separate copy of the variable with that
> combination, which was the original issue that caused us to add the
> warning. A copy is not made for getters and setters, so that's why that
> advice became common. When you prevent renaming, Closure is forced to use
> the original variable when exporting, so there is no copy, and it's safe.
> 
> --
> Josh Tynjala
> Bowler Hat LLC <https://bowlerhat.dev>
> 
> 
> On Mon, May 24, 2021 at 11:07 PM Yishay Weiss <yi...@hotmail.com>
> wrote:
> 
>> Hi Josh,
>> 
>> I still haven’t wrapped my head around all of this but thanks for the
>> informative post. Does this somehow mean public vars are now always safe to
>> use as opposed to having to covert them to public methods?
>> 
>> From: Josh Tynjala<ma...@bowlerhat.dev>
>> Sent: Monday, May 24, 2021 11:32 PM
>> To: Apache Royale Development<ma...@royale.apache.org>
>> Subject: Compiler options for reducing release build size of Royale
>> projects (Part 2)
>> 
>> Back in November, I shared a summary of some of the work that I've been
>> doing on reducing the size of release builds generated by the Royale
>> compiler. Essentially, I've been trying to ensure that we could take better
>> advantage of Closure compiler's advanced optimizations for minification,
>> which includes removing dead code and renaming symbols so that they have
>> shorter names.
>> 
>> Since then, I've made some more improvements to the Royale compiler, which
>> will allow even more optimization. I figured that it is a good time to
>> share my latest results.
>> 
>> To fully understand the context of today's post, I recommend reviewing the
>> introduction that I wrote for my earlier post (you can stop once I start
>> talking about the results). Here's the link to the archive:
>> 
>> 
>> https://lists.apache.org/thread.html/rf53d200969d795a15bda5d6635b904d89fa7f6af151df5dca15ccbbb%40%3Cdev.royale.apache.org%3E
>> 
>> Last time, in my final set of results, some public symbols were allowed to
>> be renamed in the release build, but some were not. If I tried to rename
>> all public symbols, it would cause parts of the apps to stop working
>> correctly. My work since then has been finding ways to ensure that more
>> public symbols can be renamed safely.
>> 
>> What I determined is that the way that we encode MXML data in JavaScript
>> results in a lot of dynamically setting properties using string names,
>> similar to `variable["propName"] = value`. Setting properties dynamically
>> is generally bad when minimizing with Closure compiler because it won't
>> understand that it needs to keep those properties, and it may remove them
>> as dead code (even though it's not dead code), or it may change their names
>> (while our code still uses the original names).
>> 
>> Luckly, our MXML data in JS is well-structured, so it's possible to walk
>> the JS tree when creating the release build and extract names that are used
>> dynamically in MXML. Then, we can pass those names to Closure compiler
>> manually. Basically, we're extending the Closure compiler with an extra
>> analysis step that has specialized knowledge of Royale. This allows us to
>> rename more public symbols because we can exclude the ones that we know
>> cannot be renamed).
>> 
>> I added a new compiler option, *prevent-rename-mxml-symbol-references*,
>> which defaults to true. You will probably never want to change this to
>> false, but the option is there, if anyone ever determines that it is needed
>> in some edge case.
>> 
>> Okay, now to the results. I built the same four app projects as last time.
>> 
>> I used the following commits, if anyone wants to try reproducing on their
>> own computer:
>> 
>> royale-compiler: 65805281ea898b3a0225922f5956c864f810c423
>> royale-asjs: fab5f5444e0e9ee7f8f59e5cf1d4b1144a31025e
>> spectrum-royale: acf4007fa322d61e1d0ae874e4c2009f8645654c
>> 
>> ==========
>> Baseline: royale-compiler 0.9.7
>> ==========
>> 
>> HelloWorld: 71 KB
>> ASDoc: 237 KB
>> TourDeJewel: 1125 KB
>> SpectrumBrowser: 944 KB
>> 
>> As with my previous post, I built all of the example projects with the
>> Royale 0.9.7 compiler first. However, I built them with the latest
>> framework code. This ensures that only the differences in the compiler are
>> being compared, and we don't have extra noise from differences in the
>> framework code.
>> 
>> -----
>> 
>> Now, let's see some results with the latest compiler.
>> 
>> All results below include the +/- difference in KB and %. These values are
>> always in comparison to the baseline numbers above.
>> 
>> ==========
>> Result 1: Latest compiler with default options
>> ==========
>> 
>> HelloWorld: 87 KB (+16 KB / +23%)
>> ASDoc: 261 KB (+24 KB / +10%)
>> TourDeJewel: 1159 KB (+34 KB / +3%)
>> SpectrumBrowser: 980 KB (+36 KB / +4%)
>> 
>> As with the previous post, the increase in file size here is expected. The
>> latest compiler fixes some bugs that were present in 0.9.7 that caused
>> certain symbols to be renamed/removed when they should not have been.
>> 
>> ==========
>> Result 2: Disable symbol exports and allow non-public symbols to be renamed
>> ==========
>> 
>> HelloWorld: 74 KB (+3 KB / +4%)
>> ASDoc: 226 KB (-11 KB / -5%)
>> TourDeJewel: 966 KB (-159 KB / -14%)
>> SpectrumBrowser: 897 KB (-47 KB / -5%)
>> 
>> Compiler options used:
>> *-export-public-symbols=false*
>> *-prevent-rename-protected-symbols=false*
>> *-prevent-rename-internal-symbols=false*
>> 
>> These results are consistent with a similar test from my previous post. I
>> included it to show that nothing has changed, and to have an intermediate
>> step between the default options and the full optimizations.
>> 
>> ==========
>> Result 3: Allow public symbols to be renamed too
>> ==========
>> 
>> HelloWorld: 66 KB (-5 KB / -7%)
>> ASDoc: N/A
>> TourDeJewel: N/A
>> SpectrumBrowser: 857 KB (-87 KB / -9%)
>> 
>> Compiler options used:
>> -export-public-symbols=false
>> -prevent-rename-protected-symbols=false
>> -prevent-rename-internal-symbols=false
>> *-prevent-rename-public-symbols=false*
>> 
>> This is a compiler option that I didn't include in the tests last time
>> because renaming all public symbols broke every app before. Now that the
>> Royale compiler walks the MXML data tree, it's possible to allow renaming
>> of public symbols in some apps (but not all, for reasons I will explain).
>> *This
>> combination of compiler options provides the largest possible file size
>> savings in release builds.*
>> 
>> You'll notice that ASDoc and TourDeJewel are marked N/A. This is because
>> they use the ConstantBinding class, which sets up bindings dynamically.
>> 
>> <js:ConstantBinding sourceID="listModel" sourcePropertyName="iconListData"
>> destinationPropertyName="dataProvider"/>
>> 
>> When compiled to JS, this code basically converts to this:
>> 
>> this[binding.destinationPropertyName] =
>> this[binding.sourceID][binding.sourcePropertyName];
>> 
>> Notice the bracket access with string values. Like I explained before,
>> this is something that Closure compiler cannot detect.
>> 
>> Technically, I could write another custom Closure compiler pass that looks
>> for ConstantBinding objects in the MXML data tree and extract the property
>> names. It wouldn't be hard, but what happens if new types of bindings are
>> added that work similarly? Do I just keep adding them to the compiler as
>> special cases? Or what if someone wants to use the compiler with a
>> different framework and wants to move ConstantBinding to a different
>> package? Do they need to modify the compiler too? It simply doesn't feel
>> clean to me. So, if you want to use the
>> -prevent-rename-public-symbols=false compiler option, I recommend avoiding
>> ConstantBinding. Regular bindings with curly braces {} are fully supported,
>> and they're what most people will be familiar with from Flex anyway.
>> 
>> ==========
>> Extra Result: Allow *some* public symbols to be renamed
>> ==========
>> 
>> ASDoc: 210 KB (-27 KB / -11%)
>> TourDeJewel: 927 KB (-198 KB / -18%)
>> 
>> Compiler options used:
>> -export-public-symbols=false
>> -prevent-rename-protected-symbols=false
>> -prevent-rename-internal-symbols=false
>> *-prevent-rename-public-static-methods=false*
>> *-prevent-rename-public-instance-methods=false*
>> 
>> That being said, even when using ConstantBinding or other dynamic features,
>> it may be possible to rename a subset of public symbols. Most commonly,
>> public methods are usually safe to rename because most people don't try to
>> call methods dynamically. This final extra test is consistent with a
>> similar result from my previous post.
>> 
>> That was really long, so thank you for reading, if you made it to the end!
>> 
>> --
>> Josh Tynjala
>> Bowler Hat LLC <https://bowlerhat.dev>
>> 
>> 


Re: Compiler options for reducing release build size of Royale projects (Part 2)

Posted by Josh Tynjala <jo...@bowlerhat.dev>.
Some of my earlier changes made it safe to use public variables instead of
getters/setters, at least with the compiler defaults. With certain
combinations of compiler options, it is possible to make it unsafe again,
though.

If you decided to use -export-public-symbols=true and
-prevent-rename-public-symbols=false together, for some reason (this
wouldn't be common), that would make public variables unsafe to use again.
Closure compiler would make a separate copy of the variable with that
combination, which was the original issue that caused us to add the
warning. A copy is not made for getters and setters, so that's why that
advice became common. When you prevent renaming, Closure is forced to use
the original variable when exporting, so there is no copy, and it's safe.

--
Josh Tynjala
Bowler Hat LLC <https://bowlerhat.dev>


On Mon, May 24, 2021 at 11:07 PM Yishay Weiss <yi...@hotmail.com>
wrote:

> Hi Josh,
>
> I still haven’t wrapped my head around all of this but thanks for the
> informative post. Does this somehow mean public vars are now always safe to
> use as opposed to having to covert them to public methods?
>
> From: Josh Tynjala<ma...@bowlerhat.dev>
> Sent: Monday, May 24, 2021 11:32 PM
> To: Apache Royale Development<ma...@royale.apache.org>
> Subject: Compiler options for reducing release build size of Royale
> projects (Part 2)
>
> Back in November, I shared a summary of some of the work that I've been
> doing on reducing the size of release builds generated by the Royale
> compiler. Essentially, I've been trying to ensure that we could take better
> advantage of Closure compiler's advanced optimizations for minification,
> which includes removing dead code and renaming symbols so that they have
> shorter names.
>
> Since then, I've made some more improvements to the Royale compiler, which
> will allow even more optimization. I figured that it is a good time to
> share my latest results.
>
> To fully understand the context of today's post, I recommend reviewing the
> introduction that I wrote for my earlier post (you can stop once I start
> talking about the results). Here's the link to the archive:
>
>
> https://lists.apache.org/thread.html/rf53d200969d795a15bda5d6635b904d89fa7f6af151df5dca15ccbbb%40%3Cdev.royale.apache.org%3E
>
> Last time, in my final set of results, some public symbols were allowed to
> be renamed in the release build, but some were not. If I tried to rename
> all public symbols, it would cause parts of the apps to stop working
> correctly. My work since then has been finding ways to ensure that more
> public symbols can be renamed safely.
>
> What I determined is that the way that we encode MXML data in JavaScript
> results in a lot of dynamically setting properties using string names,
> similar to `variable["propName"] = value`. Setting properties dynamically
> is generally bad when minimizing with Closure compiler because it won't
> understand that it needs to keep those properties, and it may remove them
> as dead code (even though it's not dead code), or it may change their names
> (while our code still uses the original names).
>
> Luckly, our MXML data in JS is well-structured, so it's possible to walk
> the JS tree when creating the release build and extract names that are used
> dynamically in MXML. Then, we can pass those names to Closure compiler
> manually. Basically, we're extending the Closure compiler with an extra
> analysis step that has specialized knowledge of Royale. This allows us to
> rename more public symbols because we can exclude the ones that we know
> cannot be renamed).
>
> I added a new compiler option, *prevent-rename-mxml-symbol-references*,
> which defaults to true. You will probably never want to change this to
> false, but the option is there, if anyone ever determines that it is needed
> in some edge case.
>
> Okay, now to the results. I built the same four app projects as last time.
>
> I used the following commits, if anyone wants to try reproducing on their
> own computer:
>
> royale-compiler: 65805281ea898b3a0225922f5956c864f810c423
> royale-asjs: fab5f5444e0e9ee7f8f59e5cf1d4b1144a31025e
> spectrum-royale: acf4007fa322d61e1d0ae874e4c2009f8645654c
>
> ==========
> Baseline: royale-compiler 0.9.7
> ==========
>
> HelloWorld: 71 KB
> ASDoc: 237 KB
> TourDeJewel: 1125 KB
> SpectrumBrowser: 944 KB
>
> As with my previous post, I built all of the example projects with the
> Royale 0.9.7 compiler first. However, I built them with the latest
> framework code. This ensures that only the differences in the compiler are
> being compared, and we don't have extra noise from differences in the
> framework code.
>
> -----
>
> Now, let's see some results with the latest compiler.
>
> All results below include the +/- difference in KB and %. These values are
> always in comparison to the baseline numbers above.
>
> ==========
> Result 1: Latest compiler with default options
> ==========
>
> HelloWorld: 87 KB (+16 KB / +23%)
> ASDoc: 261 KB (+24 KB / +10%)
> TourDeJewel: 1159 KB (+34 KB / +3%)
> SpectrumBrowser: 980 KB (+36 KB / +4%)
>
> As with the previous post, the increase in file size here is expected. The
> latest compiler fixes some bugs that were present in 0.9.7 that caused
> certain symbols to be renamed/removed when they should not have been.
>
> ==========
> Result 2: Disable symbol exports and allow non-public symbols to be renamed
> ==========
>
> HelloWorld: 74 KB (+3 KB / +4%)
> ASDoc: 226 KB (-11 KB / -5%)
> TourDeJewel: 966 KB (-159 KB / -14%)
> SpectrumBrowser: 897 KB (-47 KB / -5%)
>
> Compiler options used:
> *-export-public-symbols=false*
> *-prevent-rename-protected-symbols=false*
> *-prevent-rename-internal-symbols=false*
>
> These results are consistent with a similar test from my previous post. I
> included it to show that nothing has changed, and to have an intermediate
> step between the default options and the full optimizations.
>
> ==========
> Result 3: Allow public symbols to be renamed too
> ==========
>
> HelloWorld: 66 KB (-5 KB / -7%)
> ASDoc: N/A
> TourDeJewel: N/A
> SpectrumBrowser: 857 KB (-87 KB / -9%)
>
> Compiler options used:
> -export-public-symbols=false
> -prevent-rename-protected-symbols=false
> -prevent-rename-internal-symbols=false
> *-prevent-rename-public-symbols=false*
>
> This is a compiler option that I didn't include in the tests last time
> because renaming all public symbols broke every app before. Now that the
> Royale compiler walks the MXML data tree, it's possible to allow renaming
> of public symbols in some apps (but not all, for reasons I will explain).
> *This
> combination of compiler options provides the largest possible file size
> savings in release builds.*
>
> You'll notice that ASDoc and TourDeJewel are marked N/A. This is because
> they use the ConstantBinding class, which sets up bindings dynamically.
>
> <js:ConstantBinding sourceID="listModel" sourcePropertyName="iconListData"
> destinationPropertyName="dataProvider"/>
>
> When compiled to JS, this code basically converts to this:
>
> this[binding.destinationPropertyName] =
> this[binding.sourceID][binding.sourcePropertyName];
>
> Notice the bracket access with string values. Like I explained before,
> this is something that Closure compiler cannot detect.
>
> Technically, I could write another custom Closure compiler pass that looks
> for ConstantBinding objects in the MXML data tree and extract the property
> names. It wouldn't be hard, but what happens if new types of bindings are
> added that work similarly? Do I just keep adding them to the compiler as
> special cases? Or what if someone wants to use the compiler with a
> different framework and wants to move ConstantBinding to a different
> package? Do they need to modify the compiler too? It simply doesn't feel
> clean to me. So, if you want to use the
> -prevent-rename-public-symbols=false compiler option, I recommend avoiding
> ConstantBinding. Regular bindings with curly braces {} are fully supported,
> and they're what most people will be familiar with from Flex anyway.
>
> ==========
> Extra Result: Allow *some* public symbols to be renamed
> ==========
>
> ASDoc: 210 KB (-27 KB / -11%)
> TourDeJewel: 927 KB (-198 KB / -18%)
>
> Compiler options used:
> -export-public-symbols=false
> -prevent-rename-protected-symbols=false
> -prevent-rename-internal-symbols=false
> *-prevent-rename-public-static-methods=false*
> *-prevent-rename-public-instance-methods=false*
>
> That being said, even when using ConstantBinding or other dynamic features,
> it may be possible to rename a subset of public symbols. Most commonly,
> public methods are usually safe to rename because most people don't try to
> call methods dynamically. This final extra test is consistent with a
> similar result from my previous post.
>
> That was really long, so thank you for reading, if you made it to the end!
>
> --
> Josh Tynjala
> Bowler Hat LLC <https://bowlerhat.dev>
>
>

RE: Compiler options for reducing release build size of Royale projects (Part 2)

Posted by Yishay Weiss <yi...@hotmail.com>.
Hi Josh,

I still haven’t wrapped my head around all of this but thanks for the informative post. Does this somehow mean public vars are now always safe to use as opposed to having to covert them to public methods?

From: Josh Tynjala<ma...@bowlerhat.dev>
Sent: Monday, May 24, 2021 11:32 PM
To: Apache Royale Development<ma...@royale.apache.org>
Subject: Compiler options for reducing release build size of Royale projects (Part 2)

Back in November, I shared a summary of some of the work that I've been
doing on reducing the size of release builds generated by the Royale
compiler. Essentially, I've been trying to ensure that we could take better
advantage of Closure compiler's advanced optimizations for minification,
which includes removing dead code and renaming symbols so that they have
shorter names.

Since then, I've made some more improvements to the Royale compiler, which
will allow even more optimization. I figured that it is a good time to
share my latest results.

To fully understand the context of today's post, I recommend reviewing the
introduction that I wrote for my earlier post (you can stop once I start
talking about the results). Here's the link to the archive:

https://lists.apache.org/thread.html/rf53d200969d795a15bda5d6635b904d89fa7f6af151df5dca15ccbbb%40%3Cdev.royale.apache.org%3E

Last time, in my final set of results, some public symbols were allowed to
be renamed in the release build, but some were not. If I tried to rename
all public symbols, it would cause parts of the apps to stop working
correctly. My work since then has been finding ways to ensure that more
public symbols can be renamed safely.

What I determined is that the way that we encode MXML data in JavaScript
results in a lot of dynamically setting properties using string names,
similar to `variable["propName"] = value`. Setting properties dynamically
is generally bad when minimizing with Closure compiler because it won't
understand that it needs to keep those properties, and it may remove them
as dead code (even though it's not dead code), or it may change their names
(while our code still uses the original names).

Luckly, our MXML data in JS is well-structured, so it's possible to walk
the JS tree when creating the release build and extract names that are used
dynamically in MXML. Then, we can pass those names to Closure compiler
manually. Basically, we're extending the Closure compiler with an extra
analysis step that has specialized knowledge of Royale. This allows us to
rename more public symbols because we can exclude the ones that we know
cannot be renamed).

I added a new compiler option, *prevent-rename-mxml-symbol-references*,
which defaults to true. You will probably never want to change this to
false, but the option is there, if anyone ever determines that it is needed
in some edge case.

Okay, now to the results. I built the same four app projects as last time.

I used the following commits, if anyone wants to try reproducing on their
own computer:

royale-compiler: 65805281ea898b3a0225922f5956c864f810c423
royale-asjs: fab5f5444e0e9ee7f8f59e5cf1d4b1144a31025e
spectrum-royale: acf4007fa322d61e1d0ae874e4c2009f8645654c

==========
Baseline: royale-compiler 0.9.7
==========

HelloWorld: 71 KB
ASDoc: 237 KB
TourDeJewel: 1125 KB
SpectrumBrowser: 944 KB

As with my previous post, I built all of the example projects with the
Royale 0.9.7 compiler first. However, I built them with the latest
framework code. This ensures that only the differences in the compiler are
being compared, and we don't have extra noise from differences in the
framework code.

-----

Now, let's see some results with the latest compiler.

All results below include the +/- difference in KB and %. These values are
always in comparison to the baseline numbers above.

==========
Result 1: Latest compiler with default options
==========

HelloWorld: 87 KB (+16 KB / +23%)
ASDoc: 261 KB (+24 KB / +10%)
TourDeJewel: 1159 KB (+34 KB / +3%)
SpectrumBrowser: 980 KB (+36 KB / +4%)

As with the previous post, the increase in file size here is expected. The
latest compiler fixes some bugs that were present in 0.9.7 that caused
certain symbols to be renamed/removed when they should not have been.

==========
Result 2: Disable symbol exports and allow non-public symbols to be renamed
==========

HelloWorld: 74 KB (+3 KB / +4%)
ASDoc: 226 KB (-11 KB / -5%)
TourDeJewel: 966 KB (-159 KB / -14%)
SpectrumBrowser: 897 KB (-47 KB / -5%)

Compiler options used:
*-export-public-symbols=false*
*-prevent-rename-protected-symbols=false*
*-prevent-rename-internal-symbols=false*

These results are consistent with a similar test from my previous post. I
included it to show that nothing has changed, and to have an intermediate
step between the default options and the full optimizations.

==========
Result 3: Allow public symbols to be renamed too
==========

HelloWorld: 66 KB (-5 KB / -7%)
ASDoc: N/A
TourDeJewel: N/A
SpectrumBrowser: 857 KB (-87 KB / -9%)

Compiler options used:
-export-public-symbols=false
-prevent-rename-protected-symbols=false
-prevent-rename-internal-symbols=false
*-prevent-rename-public-symbols=false*

This is a compiler option that I didn't include in the tests last time
because renaming all public symbols broke every app before. Now that the
Royale compiler walks the MXML data tree, it's possible to allow renaming
of public symbols in some apps (but not all, for reasons I will explain). *This
combination of compiler options provides the largest possible file size
savings in release builds.*

You'll notice that ASDoc and TourDeJewel are marked N/A. This is because
they use the ConstantBinding class, which sets up bindings dynamically.

<js:ConstantBinding sourceID="listModel" sourcePropertyName="iconListData"
destinationPropertyName="dataProvider"/>

When compiled to JS, this code basically converts to this:

this[binding.destinationPropertyName] =
this[binding.sourceID][binding.sourcePropertyName];

Notice the bracket access with string values. Like I explained before,
this is something that Closure compiler cannot detect.

Technically, I could write another custom Closure compiler pass that looks
for ConstantBinding objects in the MXML data tree and extract the property
names. It wouldn't be hard, but what happens if new types of bindings are
added that work similarly? Do I just keep adding them to the compiler as
special cases? Or what if someone wants to use the compiler with a
different framework and wants to move ConstantBinding to a different
package? Do they need to modify the compiler too? It simply doesn't feel
clean to me. So, if you want to use the
-prevent-rename-public-symbols=false compiler option, I recommend avoiding
ConstantBinding. Regular bindings with curly braces {} are fully supported,
and they're what most people will be familiar with from Flex anyway.

==========
Extra Result: Allow *some* public symbols to be renamed
==========

ASDoc: 210 KB (-27 KB / -11%)
TourDeJewel: 927 KB (-198 KB / -18%)

Compiler options used:
-export-public-symbols=false
-prevent-rename-protected-symbols=false
-prevent-rename-internal-symbols=false
*-prevent-rename-public-static-methods=false*
*-prevent-rename-public-instance-methods=false*

That being said, even when using ConstantBinding or other dynamic features,
it may be possible to rename a subset of public symbols. Most commonly,
public methods are usually safe to rename because most people don't try to
call methods dynamically. This final extra test is consistent with a
similar result from my previous post.

That was really long, so thank you for reading, if you made it to the end!

--
Josh Tynjala
Bowler Hat LLC <https://bowlerhat.dev>