Skip to content
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

Substituting multi-use constants results in a larger bundle #3791

Closed
nikitaeverywhere opened this issue May 31, 2024 · 5 comments
Closed

Substituting multi-use constants results in a larger bundle #3791

nikitaeverywhere opened this issue May 31, 2024 · 5 comments

Comments

@nikitaeverywhere
Copy link

nikitaeverywhere commented May 31, 2024

Hello! Thanks again for the great and a fast top-notch lib.

I want to point onto a bit weird behavior when using the next config: {minify: true, treeShaking: true}.

As you can see, numbers are substituted here:

image

While the output in general could be smaller:

  • const f=n=>{let t=n+25565;return t+=51130,t+25565};return 25565+25565*2+f(25565); (actual)
  • const x=25565,f=n=>{let t=n+x;return t+=x+x,t+x};return x+x*2+f(x); (wanted)

Here's an example of my production minified code of a small library that could literally save 1.5kb just on not substituting constants.

image

I think the rule of a thumb somewhere down in the minifier could be this: do not substitute constants that are 3+ digits in length and have more than X references.

Is it possible to configure it right now? Or, if you like this suggestion and one were to make a PR, where can they start from?

Thank you.

@evanw
Copy link
Owner

evanw commented Jun 6, 2024

Those two code fragments are basically the same size after gzip. If you aren't gzipping your code, then that's likely going to be a bigger win than any tweaks to the minifier can be. And if you are gzipping your code, then your suggestion will have essentially no effect on gzipped code size.

To answer your question: one easy way to avoid inlining is to replace const for var. That has the additional benefit of running more quickly as const has more run-time overhead than var does (at least when const is not completely inlined).

@nikitaeverywhere
Copy link
Author

Those two code fragments are basically the same size after gzip. If you aren't gzipping your code, then that's likely going to be a bigger win than any tweaks to the minifier can be. And if you are gzipping your code, then your suggestion will have essentially no effect on gzipped code size.

I knew you will say that! 😃

To answer your question: one easy way to avoid inlining is to replace const for var.

Very interesting insight, thank you! I see this also works with let (does it have similar runtime overhead?). Somewhat logical but surprising behavior, actually very useful in my case as I want to prevent substituting constants.

@evanw
Copy link
Owner

evanw commented Jun 6, 2024

let is also slower than var. Both let and const require the VM to generate extra code to do additional checks that potentially throws an error if the variable is used before it's initialized. These checks can result in extreme slowdowns in older VMs and moderate slowdowns in newer VMs.

@nikitaeverywhere
Copy link
Author

Thank you, very insightful. As I additionally process the output code with terser, it transpiles everything to var.

I'm closing the issue then as there's a workaround, and somewhat I agree substituting const is an expected behavior. Thank you!

@evanw
Copy link
Owner

evanw commented Jun 7, 2024

Sounds good. Closing this issue then.

@evanw evanw closed this as not planned Won't fix, can't repro, duplicate, stale Jun 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants