
Angular application bundles using Rollup, Webpack and the Closure compiler - thelgevold
http://www.syntaxsuccess.com/viewarticle/angular-application-bundles
======
rpeden
I've long felt that the front end community could benefit from making heavier
use of the Closure Compiler. It has been very good for a very long time now.

The downside to its age is that it likes to do things its own way; it's had a
static module system since _long_ before ES2015 modules or even CommonJS
modules existed. It does have support for other module systems now, though.
And as the article mentions, it performs optimizations far beyond what other
JS tools do.

One of the big things people disliked about the compiler is that to get
maximum optimizations out of it, you had to write your JS in a relatively
static way, preferably with JSDoc type annotations.

This is less of a barrier now, I think; TypeScript has become quite popular in
the front end community, and the Angular team has created TSickle[1], which
allows the TypeScript compiler to output Closure annotated JS.

Webpack is a lot more capable, but also results in shipping a much larger code
bundle to your users. This might not matter so much for desktop clients, but
in many parts of the world, mobile users still have pretty restrictive data
caps, and overages are very expensive.

[1][https://github.com/angular/tsickle](https://github.com/angular/tsickle)

------
jkaptur
The Closure ecosystem definitely evolved a bit differently from the rest of
the JS world, but it pioneered some techniques 10 years ago that the rest of
the community is only now rediscovering, like isomorphic rendering and type
checking. Soon we'll probably see something that minimizes CSS (I'm joking -
I'm sure there's a webpack plugin, but I'd be surprised if it were as high
quality).

It's an interesting case study in why developer UX is so important - Closure
never really "fit in" with other tools, which I think really hurt its
adoption.

------
didibus
I'd also recommend people interested in the Google Closure Library to try out
ClojureScript. All ClojureScript code and libraries are automatically
compatible with Google's Closure compiler advanced compilation.

It supports working with JavaScript libraries who are also compatible, or at
the sacrifice of less optimizations, it lets you work with non compatible
JavaScript libraries also.

For example for Angular, you just need to specify an extern file. It will
still optimize parts of it, but it won't do symbol renaming. (Disclaimer, I've
never actually tried to use Angular with CLJS, but I believe this is true)

For libraries which are completly non compatible, you can import them as
foreign libraries and they'll just bypass the advanced compilation, but all
your CLJS code and everything else which can be optimized will.

Here's a template to get you started with Angular2 and CLJS
[https://github.com/steveshogren/angular2-cljs](https://github.com/steveshogren/angular2-cljs)

------
thelgevold
Hi. The author of the article here.

The webpack and Rollup experiments were done with uglify and gzip enabled. The
numbers are based on the reported values in Chrome when running the code here:
[http://www.syntaxsuccess.com/rollup-
bundle](http://www.syntaxsuccess.com/rollup-bundle)
[http://www.syntaxsuccess.com/webpack-
bundle](http://www.syntaxsuccess.com/webpack-bundle)
[http://www.syntaxsuccess.com/closure-
bundle](http://www.syntaxsuccess.com/closure-bundle)

The uglify code was accidentally commented out in the source on Github, but I
have fixed that now.

------
franciscop
I am really curious about the minimized and gzipped size differences. I
created a library a while back[1] and experimented with extreme fileweight
(it's an alternative to jQuery with just 3kb minimized + gzipped). I also
wrote the topic from what I learned:

[https://medium.com/@fpresencia/understanding-gzip-
size-836c7...](https://medium.com/@fpresencia/understanding-gzip-
size-836c74b66c0b)

Depending on the code, even if it seems quite large initially it might
minimize and gzip quite well. Actually, automatic code generation is the
perfect candidate for a good compression. One of the reasons is because this:

    
    
        (function(module, __webpack_exports__, __webpack_require__) {})
    

Will become just:

    
    
       (function(a,b,c){})
    

Which is 5char/function difference with the other example shown in the article
with uglify. It becomes negligible when we take into account gzip, since that
will be stored only once and then it's just 5char difference overall. So an
apparent "module, __webpack_exports__, __webpack_require__" x N becomes just
5bytes of difference in total.

[1] [http://umbrellajs.com/](http://umbrellajs.com/)

~~~
rpeden
It's useful to consider not just download size, but also the time required to
parse the extra code, and the extra memory used by the code that's parsed and
loaded into memory, but not actually used.

 _Probably_ not a concern for desktop/laptop users, but there are plenty of
mobile devices out there with relatively slow processors and 1GB of RAM or
less.

~~~
franciscop
Totally, however that article was mainly about compression file size.

The main problem when we get to optimization is that it highly depends on the
browser and version. Parse time is still important, but I'd argue that it's
related to both file size and processing power needed, but still less
important than both of those.

------
feedic
This isn't an apples to apples comparison, as Uglify is disabled for Webpack
and Rollup. Of course they are larger without minification.

~~~
thelgevold
It was accidentally committed commented out for debugging, but the numbers
from the experiments use uglify and gzip. Updated the repo as well now.

------
k__
Didn't the Rollup creator claim that Rollup always makes the smallest bundles
and if not, it's a wrong Rollup config?

~~~
rich_harris
Rollup creator here. You're thinking of this tweet[0] which states that
correctly configured Rollup bundles are always smaller than _Webpack_ bundles.
Closure Compiler on the other hand is currently far more sophisticated than
either Rollup or Webpack when it comes to shrinking your code. It's just a
little bit harder to use and makes certain assumptions about your code, which
is probably why it often doesn't get quite as much attention (though Malte
Ubl's splittable[1] provides a nice interface onto CC and supports code
splitting — well worth a look).

[0]:
[https://twitter.com/Rich_Harris/status/820304090332876800](https://twitter.com/Rich_Harris/status/820304090332876800)
[1]:
[https://github.com/cramforce/splittable](https://github.com/cramforce/splittable)

~~~
k__
Ah yes, thanks :)

------
CapacitorSet
The Closure Compiler with ADVANCED_OPTIMIZATION is a great tool, and I wish
more projects used it. However, when I tried it on my own projects I found
that it is a relative pain in the arse to export absolutely everything that
you don't want the compiler to remove or rename: this might be why it didn't
gain a lot of traction.

------
hokkos
Benchmark like this are not useful if they are not real world. It means you
should show minified and gzipped size, the same long signature in webpack will
be heavily compressed. Also the TypeScript usage will lead to better
optimizations with a TypeScript loader in Webpack.

------
micimize
I assume the uglify plugin wasn't commented out when the actual test was run.

I haven't tried this myself, but it's worth noting that you can use closure
with webpack: [https://github.com/roman01la/webpack-closure-
compiler](https://github.com/roman01la/webpack-closure-compiler)

Hopefully it won't be long before frameworks still depending on html templates
are mostly implementing them with es6 tagged template literals, which will
make them available for compiler optimizations.

~~~
k__
I use t7 with (P)React, which works quite nicely :)

~~~
micimize
I hadn't heard of t7 - looks very nice. Similar to
[https://github.com/maxogden/yo-yo](https://github.com/maxogden/yo-yo), but
I'm impressed with the level of React inter-op and spread support.

I meant more on like Angular implementing it's html templates using template
literals and importing them into the runtime, making them inspectable. On
second thought, it might be less a matter of the underlying logic and more a
matter of when templates are evaluated

------
nickhalfasleep
The closure compiler is a very smart system, and was ahead of it's time in
many ways, but now you can get type checking and stronger OO behaviors without
being so verbose.

I'm on a team with a moderately large frontend written with the closure
compiler, and we are looking forward to using other libraries on new projects.

