Google Groupes

Experiments in minifying generated Elm code


Erik Simmler 29 mars 2017 19:11
Envoyé au groupe : elm-dev
I've been experimenting on some compiled Elm code in attempt to optimize final file size as much as practical (https://github.com/tgecho/babel-plugin-elm-pre-minify)

The short version is that I was able to improve on vanilla uglify or closure results from 15% to over 40%. I did this by using a Babel plugin to surgically restructure some of the code based on assumptions I was able to make about how Elm's output is structured (pure functions, etc...). For example:

## elm-todomvc
file                  raw     gzip   zopfli
original.js           228750  43995  41480
vanilla-uglify.js     80394   23163  22276
vanilla-closure.js    71191   21981  21186
optimized-closure.js  60971   18574  17919
optimized-uglify.js   39882   12773  12319

There are two main techniques I used:

IIFE Unwrapping
Minifiers won't eliminate any expressions with potential side effects. Even accessing properties isn't safe due to getters.

var couldBeUnwrapped = function() {
 
return {exposedFunction: function() {}};
}();
var referenceToWrappedFunction = couldBeUnwrapped.exposedFunction;

Flattens out to allow minifiers to eliminate any unused functions/variables.

var couldBeUnwrapped = {},
 couldBeUnwrapped$iife_public$exposedFunction
= function() {};
var referenceToWrappedFunction = couldBeUnwrapped$iife_public$exposedFunction;


Pure function annotation
Elm uses the F2..9 functions as internal helpers, but minifiers see them as a potential source of side effects, and so won't eliminate any expressions they are used in. Uglify recently added support for annotating a function call as pure.

var potentiallyUnusedVar = /* #__PURE__ */F2(someFunc);


Feedback welcome! I'd be especially curious if anyone thinks this specific tool is actually a good idea! :)  I'm not sure I feel comfortable with it as a long term approach, but I hope some of what I've learned might prove useful in future work on dead code elimination and other size related optimizations. More info (including results from a few other projects) is in the repo: https://github.com/tgecho/babel-plugin-elm-pre-minify