Did anybody ever use Prepack or Google closure compiler with Elm 0.18's compiled JavaScript?

I tried both of them to optimize / remove dead code, and both failed, because of some error. The Elm file compiled to JavaScript was a simple hello world example

1 Like

I use closure compiler version v20171203 with --compilation_level SIMPLE_OPTIMIZATIONS It gives a few warnings but works fine. Newer versions can’t process my code and output errors. Note that SIMPLE_OPTIMIZATIONS doesn’t remove dead code.

2 Likes

Use uglifyjs or, if you don’t want to bother with the options, use elm-minify (which uses uglifyjs behind the scene).

Sample command:

uglifyjs elm.js --compress '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' | uglifyjs --mangle --output=elm.min.js
2 Likes

I used elm-minify and it worked fine. The concept of Prepack is different than minification or dead-code-removal (which Google Closure Compiler does). It eliminate computations which can be done on compile time, so the app runs faster during runtime (having to deal with less computations). Google Closure compiler may also be doing something similar when the “advanced” option is chosen (I’m not sure about that).
Though it’s not necessary, but I thought if somebody already did it, getting the benefits for free is a good thing. :slight_smile:

Out of curiosity, I tried using prepack on a simple Counter app. It worked in that it produced some .js file that behaved properly. The funny thing is that elm-minify on the prepack version produced a large minified version than running it on the compiler output.

so Main.elm > compiler > prepack > uglifyjs produces a file that is larger than Main.elm > compiler > uglifyjs.

I have tested it on the elm-spa-example and the difference remains. (93k for the uglifyjs only vs 114k for prepack + uglifyjs)

It would be wonderful to have compile time function evaluation native in the elm compiler when the --optimize would be used. This would allow for even smaller sizes but it is not a trivial optimization.

2 Likes

This is interesting. I guess the compiler would have to run the elm code to do that, and therefore it would have to run some javascript (requiring nodejs), wouldn’t it?

Not necessarily. I imagine that a restricted version of this functionality could be implemented without going through JS. Imagine implementing an eval function that would be able to evaluate some Elm code by using Haskell’s functions. It might not be able to evaluate every piece of Elm code but it doesn’t need to. The compile time execution can be provided for a restricted set of elm functions and ignored for what it cannot do. For example, it can provide execution of operations on Int, Float, String and maybe on very simple custom types.

In any case, it would not be trivial and I’m not familiar with the compiler implementation so I might be talking nonsense.

I believe that prepack targets speed of execution and initial parse/execution optimizations so it is like an optimizing compiler, rather than a minifier.

Then I wonder what it would do with the js equivalent of:

range : List Int
range = List.range 0 42000

Would it pre-compute it?

If it is in the top level and run on the first pass, then yes. See example

1 Like

We use the google closure compiler with great success for Elm 0.18! We run it using the webpack-closure-compiler for webpack, but only for production builds (for speed reasons).

https://www.npmjs.com/package/webpack-closure-compiler

But you do need the correct version of Java installed locally for it to work correctly–the JDK.

https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.