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