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

can't get --pure to further minify/optimize elm generated JS #731

Closed
kzc opened this issue Jan 31, 2021 · 6 comments
Closed

can't get --pure to further minify/optimize elm generated JS #731

kzc opened this issue Jan 31, 2021 · 6 comments

Comments

@kzc
Copy link
Contributor

kzc commented Jan 31, 2021

I'm trying to get a comparable esbuild minified size for the JS in https://evancz.github.io/elm-todomvc/ using instructions adapted from https://guide.elm-lang.org/optimization/asset_size.html:

The original JS:

$ curl -sO https://evancz.github.io/elm-todomvc/elm.js

$ wc -c elm.js
  206002 elm.js

I can't seem to get esbuild to further optimize code as recommended in the elm optimization guide above:

$ esbuild elm.js --minify | wc -c
   78621

$ esbuild elm.js --minify --pure:F2 --pure:F3 --pure:F4 --pure:F5 | wc -c
   78621

$ esbuild elm.js --bundle --minify | wc -c
   78714

$ esbuild elm.js --bundle --minify --pure:F2 --pure:F3 --pure:F4 --pure:F5 | wc -c
   78714

Is there an option that I'm failing to specify?

For comparison here's the minified size using terser with default optimizations and no pure functions specified:

$ npx terser elm.js -mc | wc -c
   68602

Here's the minified size using terser with default optimizations and just the first four pure functions listed in the elm optimization instructions:

$ npx terser elm.js -mc pure_funcs=[F2,F3,F4,F5] | wc -c
   56287

Minified size using terser with all pure functions listed and other optimizations:

$ npx terser elm.js -mc pure_funcs=[F2,F3,F4,F5,F6,F7,F8,F9,A2,A3,A4,A5,A6,A7,A8,A9],pure_getters,keep_fargs=false,unsafe_comps,unsafe,passes=2 | wc -c
   52968
@evanw
Copy link
Owner

evanw commented Feb 1, 2021

The --pure flag only applies to global (i.e. unbound) variables. See also https://esbuild.github.io/api/#pure. It seems imprecise to me to specify the feature otherwise because there could be many local variables with that name and you might not want that flag to apply to everything with that name across all files. I haven't seen a use case for this before though, so thank you for the information about the use case.

@kzc
Copy link
Contributor Author

kzc commented Feb 1, 2021

I see. Closing issue as not supported.

@kzc kzc closed this as completed Feb 1, 2021
@kzc
Copy link
Contributor Author

kzc commented Feb 1, 2021

Curious... /*@__PURE__*/ annotations on calls should work on bound variables as shown here:

$ echo '(() => {function f(x){console.log(x)} /*@__PURE__*/f("DROP"); f("KEEP");})();' | esbuild --minify
(()=>{function o(n){console.log(n)}o("KEEP")})();

Yet when a regex search/replace was used to inject a /*@__PURE__*/ annotation before every call to each of F2,F3,F4,F5,F6,F7,F8,F9,A2,A3,A4,A5,A6,A7,A8,A9, no improvement is seen:

$ esbuild elm-pure-annotated.js --bundle --minify | wc -c
   78714

Contrast this to terser with default optimizations and no pure_funcs specified:

$ npx terser elm-pure-annotated.js -mc | wc -c
   55163

and terser with advanced optimizations and no pure_funcs specified:

$ npx terser elm-pure-annotated.js -mc pure_getters,keep_fargs=false,unsafe_comps,unsafe,passes=2 | wc -c
   52968

This size is identical to the final terser command on the unannotated elm.js in the top post and has the same SHA:

$ npx terser elm.js -mc pure_funcs=[F2,F3,F4,F5,F6,F7,F8,F9,A2,A3,A4,A5,A6,A7,A8,A9],pure_getters,keep_fargs=false,unsafe_comps,unsafe,passes=2 | shasum
d2e04efc2b94493b25b060f5a116c40807506411  -
$ npx terser elm-pure-annotated.js -mc pure_getters,keep_fargs=false,unsafe_comps,unsafe,passes=2 | shasum
d2e04efc2b94493b25b060f5a116c40807506411  -

@kzc kzc reopened this Feb 1, 2021
@evanw
Copy link
Owner

evanw commented Feb 1, 2021

Most tree shaking only works at the top level in esbuild. This is a known limitation. See also #639. The straightforward workaround is to use esbuild to add the outer IIFE wrapper.

@kzc
Copy link
Contributor Author

kzc commented Feb 1, 2021

I understand the top level DCE limitation, but don't follow the IIFE wrapper comment. What command do you suggest as a workaround to improve minify size?

$ esbuild elm-pure-annotated.js --format=iife --minify --bundle | wc -c
   78714

$ esbuild elm-pure-annotated.js --format=iife | esbuild --minify | wc -c
   78717

@kzc
Copy link
Contributor Author

kzc commented Feb 1, 2021

I now see the IIFE wrapper comment was in relation to #639.

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