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" <harbs.li...@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 <harbs.li...@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.li...@gmail.com 
<mailto:harbs.li...@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 <joshtynj...@bowlerhat.dev 
<mailto:joshtynj...@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.
    >> 
    > 


Reply via email to