-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add passes
compress option. Fix duplicate compress warnings.
#1040
Conversation
I'm not sure whether introducing iterations is a good solution. It works, obviously, but it'd be much nicer to fix the core issue. |
There is no single core issue. It's not specific to this particular issue or any individual optimization. Finding a perfectly optimal compress algorithm in all situations is intractable because of the order in which individual AST node optimizations are applied - particularly when compress options are enabled or disabled in different combinations. What optimization order works best for one JS program will not necessarily be optimal for another. Presently uglify marks an AST node as being optimized to prevent an infinite compress cycle as transformed code can flip/flop between states. The default would remain at a single pass and run at the same speed. Giving the user the option to run the compress pass more than once to squeeze extra bytes from their JS at the expense of uglify running for a little more time is a good compromise, and it is not uncommon in compilers. |
|
passes
compress option.passes
compress option. Fix duplicate compress warnings.
@mishoo Any objection to merging this PR? |
I stand by my previous words, but I don't see a reason not to include this option anyway. Merged as c55dd5e, thanks! |
I've observed |
AST_Node.warn.apply(AST_Node, arguments); | ||
compress: function(node) { | ||
var passes = +this.options.passes || 1; | ||
for (var pass = 0; pass < passes && pass < 3; ++pass) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kzc Mind explaining the implicit maximum of 3 passes? My assumption is that it's an arbitrary "good enough" amount that prevents the user from shooting their foot. However I still feel it should be mentioned in the readme.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is arbitrary. I haven't seen any JS input that produces smaller output with more than 3 passes, and each additional pass makes minification slower. If you can demonstrate code that appreciably benefits from a higher number we will reconsider increasing the value.
If you wish to make a PR mentioning its max value of 3, that would be great.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense - thanks so much.
I'm putting together a PR tackling the side_effects
option with passes
- since pure annotations are removed on the first pass, thus removing the benefit of multiple passes. I'm having a hard time creating a small reproduction of code that doesn't get fully minified in one pass though - it's an interesting problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since pure annotations are removed on the first pass, thus removing the benefit of multiple passes
That hasn't been my experience with #__PURE__
annotations. Test different passes
settings in the following examples:
#1261 (comment)
#1261 (comment)
#1261 (comment)
Also, you can set an option to keep the pure annotation comments if you want uglify to emit them after minification.
Clarification: the /*#__PURE__*/
annotation is not set on a function, but a function call. I had missed that in the recent README doc fix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm - thanks for the test references. Seems I need to better understand my problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the misunderstanding - you were right and my issue was not thoroughly marking the functions I needed to. I'll put together the PR for max passes now.
Added new method
Compressor.prototype.compress(node)
to facilitate thepasses=n
optimization to further compress code in some cases.Also added basic sanity test for
minify()
.