Optimizing an Angular App with the AoT compilation
On a large Angular project, it may happen that there are slowdowns in the page loading. To reduce this time, we have implemented several optimizations, the main one being the AoT compilation.
The AoT compilation provides a pre-compiled version of the application, which eliminates the compilation time when the page is loading. Moreover, with the AoT compilation, it is no longer necessary to integrate the Angular compiler into the application.
Ideally, this compilation must be set up from the beginning of the project, because it is a tedious and difficult task to debug once the codebase is very large.
To do this, we used the webpack AotPlugin in the production configuration (which allows us to keep the conventional JIT compilation during development).
First, you will need to install the ngtools / webpack package:
Then add the following rule to your webpack production configuration:
Make sure to remove the basic rule on
.ts files and to place it only in your local configuration file:
Finally, add the AoT plugin to the list of plugins in your webpack production configuration:
Then, set a command of your
package.json to create the build with your production configuration:
At first, it will be necessary to correct the various “simple” errors that you will get at the output of your build: a classic error is the use of non-public variables in the html templates.
You may then encounter other issues as you set up the configuration. Here is what has been done to overcome these difficulties: npm-shrinkwrap.
Whatever the package manager you use, it is absolutely essential to create a file to fix the different package versions. It’s really important, and we had it from the beginning of the project development. Without this file, it is difficult to guarantee a clean and clear project from one machine to another.
In addition to the npm shrinkwrap command, we use the npm-shrinkwrap package, which ensures that the node modules, the
package.json and the
npm-shrinkwrap.json are on the same page. It also prunes some unused fields in the npm-shrinkwrap.
Typescript and node version
It seems that the AoT compilation is not supported by the recent versions of Typescript. We fixed the version at 2.2.2. Similarly for node: we use nvm to manage several node versions simultaneously, as well as a
.nvmrc file specifying the node version to use for this project. We fixed the version at 7.10.1. You may encounter this type of error when trying to use the AoT compilation with node 5:
Priority of Webpack plugins
This is not necessarily obvious, and sometimes it is not important, but the order of the different plugins that you apply in webpack has an influence on the output build. In this case, the AoT plugin must be placed first in the list of plugins of the configuration. Thus, if you need to merge several configurations, the configuration containing the AoT plugin must be the first argument of the webpackMerge. Without this, we could not get our “chunk” files corresponding to the various lazy-loaded modules of the application.
See the article on webpack here.
This webpack plugin allows analysing the different imports used by the application. It can be used completely outside the AoT setup, it allowed us to optimize the size of our application by removing unnecessary imports.
Before AOT compilation:
Not surprisingly, the libraries used, as well as Angular itself, represent most of our application (1.3 MB). The total size of the application is 2.8 MB (excluding assets).
The application takes about 2 seconds to load.
After AOT compilation:
Conclusion and possible improvement
Setting up the AOT compilation, although a tedious task, allowed us to gain considerable loading time when launching the application. Together with the lazy-loaded modules, we can offer a pleasant and fluid user experience. It would still be possible to improve the size of the application by analyzing more precisely the libraries used: for example, the moment.js library loads all the package locales, but we do not use them all. To import only the locales actually used, we have added to the list of webpack plugins the following line to load only the French and English locales: