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 |