From the summer 2016 production release of Angular, most users have treated AOT as a future curiosity. As of late fall 2016 though, many (particularly those working on larger applications) have been much more eager and interested to use AOT. Here at Oasis Digital, we have recently updated our Angular 2+ curriculum to ensure the numerous code examples used in class are AOT-ready.
Although most of our production Angular 2+ work uses the Google-sponsored Angular CLI (which was excellent AOT support), we’ve also been working with various alternative tooling stacks. Some of our customers integrate their Angular applications with broader build processes and are looking for more fine-grained control than they get with the official CLI.
Last week, Angular 4 rc.1 shipped with additional library packaging bundles, FESM and ES2015 FESM. These should support tighter production builds them before, and more easily; the official CLI does not take advantage of these yet (though I expect it will soon), and I was eager to experiment.
The results
https://github.com/OasisDigital/angular-aot-es2015-rollup/tree/master
In this example, the build is performed using:
- AOT (ngc
- Rollup
- Buble
- Uglify
See the README in the project for a lengthy explanation of how it works and why these tools were chosen. It was mostly straightforward to make this work; the configuration is quite simple. However, as of the beginning of March 2017 there is an important Rollup plug-in which does not yet have the ability to consume the new Angular ES2016 FESM bundles. To work around that, I published a (hopefully temporary) fork of that plug-in, “@oasisdigital/rollup-plugin-node-resolve“.
Another variation
The boring, excellent, proven, and still frequently updated Google Closure Compiler can often produce better results than newer, hip tools. Therefore the following variation/branch:
https://github.com/OasisDigital/angular-aot-es2015-rollup/tree/closure-compiler
…replaces a couple of the tools with Closure Compiler. It uses only:
- AOT (ngc)
- Rollup
- Closure Compiler
With fewer tools, it produces a smaller results. The configuration is slightly more complex (mostly because the Closure Compiler JavaScript port is not quite the same as the Java edition yet), but is still quite manageable.
I have not yet compared this with an even shorter stack (using Closure Compiler for the tree shaking as well), as there are examples around already doing that; but I expect an upcoming enhancement to Closure Compiler will add the “es2015” package field support needed for the ES2015 FESM bundles, once that is in place I am curious as to whether Rollup or Closure (both very respected as excellent tree shaking tools) will produce tighter results.
Why this matters
For projects deployed on an intranet, it’s possible that none of this matters. A very large internal enterprise project might ship a total of 6 MB of compressed JavaScript (hopefully divided across various bundles littered on demand) with the default tooling, or 5 MB with tweaked tooling. That won’t matter across a gigabit network with people mostly using an application frequently (and therefore with the JavaScript mostly in cache.
But not all projects are huge or internal. Angular is also well-suited for medium-to-large projects deployed on the open Internet to a huge number of sporadic users. For these users, who might be on slow connections, saving bytes counts. Faster load times translate to more user engagement. Better production bundling expands the reach of Angular two more kinds of projects.
The above is not even counting mobile; as Angular mobile application development continues to increase, the tightest possible production bundles will matter more and more.