In this article I will show how to use the ahead of time compiler (AOT) in Angular to improve performance.

Before our application can be rendered, the browsers has to do a fair amount of processing to convert all the Angular specific syntax to regular JavaScript. This process of evaluating binding expressions and parsing templates is called compilation.

As part of compilation, html templates are converted to executable JavaScript that the browser will execute to render the application.

By default compilation is done by the browser at runtime, but the idea behind AOT compilation is to take this processing offline and do it as a build step instead. Depending on the complexity of our templates, doing the compilation offline, may lead to noticeable performance improvements. It also helps reduce the size of Angular itself since we no longer have to send the compiler to the browser.

Another benefit of AOT compilation is that it sets the stage for “Tree shaking”. Basically, "Tree shaking" refers to walking our code dependency “tree” and shaking out any unused code. By “unused code” we are mainly referring to parts of Angular that our application doesn't need. As an example, if your application doesn't need forms functionality, it doesn't make sense to include it in the payload.

Tree shaking and AOT compilation are two different steps, but AOT compilation makes the code more tree shakable by converting templates from Html to JavaScript. The tree shaker can't access Html, but by converting our Html to JavaScript after AOT compilation, the Tree shaker can process more of our application and do a better job.

Bootstrapping

Using the AOT compiler requires a little bit of setup, but luckily there are very few changes to how we write our code. The most noticeable change is in the bootstrapping code. In the following code sample I have modified the standard bootstrap code to work with AOT compiled code.

import { platformBrowser } from '@angular/platform-browser'; import { AppModuleNgFactory } from './app/app.module.ngfactory'; platformBrowser().bootstrapModuleFactory(AppModuleNgFactory);

As we can see, there are a few obvious changes.

Before, we used to import an AppModule and pass it to the bootstrap method, but now we're importing a generated AppModuleNgFactory instead. Notice that we are importing angular/platform-browser instead of angular/platform-browser-dynamic to get access to the bootstrapModuleFactory method.

Where does AppModuleNgFactory come from?

AppModuleNgFactory is generated by the compiler based on our original AppModule. In addition to converting the AppModule, the compiler will generate NgFactories for all our components as well. The generated NgFactory is not a direct replacement for the component class, but we can think of it as a JavaScript representation of the component template. The NgFactory will actually refer to the original component class, so we still need both.

Compilation

The Angular team has given us a compiler cli that greatly simplifies the compilation process. It's available as an npm install

npm install @angular/compiler-cli

Once we have the compiler-cli we call

./node_modules/.bin/ngc -p [path to a tsconfig.json file]

Aside from the bootstrapping code, the rest of our code is just standard Angular code.

Demo

I have a fairly extensive sample application at this point, so I figured it would make for a good use case for AOT and tree shaking. The deployed application can be found here in case you are interested in seeing the results. The AOT compiled and minified bundle is called bundle.js

The source code for my application can be found here