This cookbook describes how to radically improve performance by compiling _Ahead of Time_ (AOT)
during a build process.
{@a toc}
## Table of Contents
* [Overview](#overview)
* [_Ahead-of-Time_ vs _Just-in-Time_](#aot-jit)
* [Compile with AOT](#compile)
* [Bootstrap](#bootstrap)
* [Tree Shaking](#tree-shaking)
* [Load the bundle](#load)
* [Serve the app](#serve)
* [Workflow and convenience script](#workflow)
* [Source Code](#source-code)
* [Tour of Heroes](#toh)
{@a overview}
## Overview
An Angular application consist largely of components and their HTML templates.
Before the browser can render the application,
the components and templates must be converted to executable JavaScript by the _Angular compiler_.
<ahref="https://www.youtube.com/watch?v=kW9cJsvcsGo"target="_blank">Watch compiler author Tobias Bosch explain the Angular Compiler</a> at AngularConnect 2016.You can compile the app in the browser, at runtime, as the application loads, using the **_Just-in-Time_ (JIT) compiler**.
This is the standard development approach shown throughout the documentation.
It's great .. but it has shortcomings.
JIT compilation incurs a runtime performance penalty.
Views take longer to render because of the in-browser compilation step.
The application is bigger because it includes the Angular compiler
and a lot of library code that the application won't actually need.
Bigger apps take longer to transmit and are slower to load.
Compilation can uncover many component-template binding errors.
JIT compilation discovers them at runtime which is later than we'd like.
The **_Ahead-of-Time_ (AOT) compiler** can catch template errors early and improve performance
by compiling at build time as you'll learn in this chapter.
{@a aot-jit}
## _Ahead-of-time_ (AOT) vs _Just-in-time_ (JIT)
There is actually only one Angular compiler. The difference between AOT and JIT is a matter of timing and tooling.
With AOT, the compiler runs once at build time using one set of libraries;
With JIT it runs every time for every user at runtime using a different set of libraries.
### Why do AOT compilation?
*Faster rendering*
With AOT, the browser downloads a pre-compiled version of the application.
The browser loads executable code so it can render the application immediately, without waiting to compile the app first.
*Fewer asynchronous requests*
The compiler _inlines_ external html templates and css style sheets within the application JavaScript,
eliminating separate ajax requests for those source files.
*Smaller Angular framework download size*
There's no need to download the Angular compiler if the app is already compiled.
The compiler is roughly half of Angular itself, so omitting it dramatically reduces the application payload.
*Detect template errors earlier*
The AOT compiler detects and reports template binding errors during the build step
before users can see them.
*Better security*
AOT compiles HTML templates and components into JavaScript files long before they are served to the client.
With no templates to read and no risky client-side HTML or JavaScript evaluation,
there are fewer opportunities for injection attacks.
{@a compile}
## Compile with AOT
### Prepare for offline compilation
Take the <ahref='../guide/setup.html'>Setup</a> as a starting point.
A few minor changes to the lone `app.component` lead to these two class and html files:
Setting a global `module` is a temporary expedient.
### Compiling the application
Initiate AOT compilation from the command line using the previously installed `ngc` compiler by executing:
<code-examplelanguage="none"class="code-shell">
node_modules/.bin/ngc -p tsconfig-aot.json
</code-example>
Windows users should surround the `ngc` command in double quotes:
<code-exampleformat='.'>
"node_modules/.bin/ngc" -p tsconfig-aot.json
</code-example>
`ngc` expects the `-p` switch to point to a `tsconfig.json` file or a folder containing a `tsconfig.json` file.
After `ngc` completes, look for a collection of _NgFactory_ files in the `aot` folder (the folder specified as `genDir` in `tsconfig-aot.json`).
These factory files are essential to the compiled application.
Each component factory creates an instance of the component at runtime by combining the original class file
and a JavaScript representation of the component's template.
Note that the original component class is still referenced internally by the generated factory.
The curious can open the `aot/app.component.ngfactory.ts` to see the original Angular template syntax
in its intermediate, compiled-to-TypeScript form.
JIT compilation generates these same _NgFactories_ in memory where they are largely invisible.
AOT compilation reveals them as separate, physical files.
~~~ {.alert.is-important}
Do not edit the _NgFactories_! Re-compilation replaces these files and all edits will be lost.
~~~
{@a bootstrap}
## Bootstrap
The AOT path changes application bootstrapping.
Instead of bootstrapping `AppModule`, you bootstrap the application with the generated module factory, `AppModuleNgFactory`.
Make a copy of `main.ts` and name it `main-jit.ts`.
This is the JIT version; set it aside as you may need it [later](#run-jit "Running with JIT").
Open `main.ts` and convert it to AOT compilation.
Switch from the `platformBrowserDynamic.bootstrap` used in JIT compilation to
`platformBrowser().bootstrapModuleFactory` and pass in the AOT-generated `AppModuleNgFactory`.
Here is AOT bootstrap in `main.ts` next to the original JIT version:
<md-tab-group>
<md-tablabel="src/main.ts">
{@example 'cb-aot-compiler/ts/src/main.ts'}
</md-tab>
<md-tablabel="src/main-jit.ts">
{@example 'cb-aot-compiler/ts/src/main-jit.ts'}
</md-tab>
</md-tab-group>
Be sure to recompile with `ngc`!
{@a tree-shaking}
## Tree Shaking
AOT compilation sets the stage for further optimization through a process called _Tree Shaking_.
A Tree Shaker walks the dependency graph, top to bottom, and _shakes out_ unused code like
dead needles in a Christmas tree.
Tree Shaking can greatly reduce the downloaded size of the application
by removing unused portions of both source and library code.
In fact, most of the reduction in small apps comes from removing unreferenced Angular features.
For example, this demo application doesn't use anything from the `@angular/forms` library.
There is no reason to download Forms-related Angular code and tree shaking ensures that you don't.
Tree Shaking and AOT compilation are separate steps.
Tree Shaking can only target JavaScript code.
AOT compilation converts more of the application to JavaScript,
which in turn makes more of the application "Tree Shakable".
### Rollup
This cookbook illustrates a Tree Shaking utility called _Rollup_.
Rollup statically analyzes the application by following the trail of `import` and `export` statements.
It produces a final code _bundle_ that excludes code that is exported, but never imported.
Rollup can only Tree Shake `ES2015` modules which have `import` and `export` statements.
Recall that `tsconfig-aot.json` is configured to produce `ES2015` modules.
It's not important that the code itself be written with `ES2015` syntax such as `class` and `const`.
What matters is that the code uses ES `import` and `export` statements rather than `require` statements.Install the Rollup dependencies with this command:
github repository and prepared it for development as explained in the repo's README.md.
The _Tour of Heroes_ source code is in the `public/docs/_examples/toh-6/ts` folder.
~~~
Run the JIT-compiled app with `npm start` as for all other JIT examples.
Compiling with AOT presupposes certain supporting files, most of them discussed above.
<md-tab-group>
<md-tablabel="src/index.html">
{@example 'toh-6/ts/src/index.html'}
</md-tab>
<md-tablabel="copy-dist-files.js">
{@example 'toh-6/ts/copy-dist-files.js'}
</md-tab>
<md-tablabel="rollup-config.js">
{@example 'toh-6/ts/rollup-config.js'}
</md-tab>
<md-tablabel="tsconfig-aot.json">
{@example 'toh-6/ts/tsconfig-aot.json'}
</md-tab>
</md-tab-group>
Extend the `scripts` section of the `package.json` with these npm scripts:Copy the AOT distribution files into the `/aot` folder with the node script:
<code-examplelanguage="none"class="code-shell">
node copy-dist-files
</code-example>
You won't do that again until there are updates to `zone.js` or the `core-js` shim for old browsers.Now AOT-compile the app and launch it with the `lite` server:
<code-examplelanguage="none"class="code-shell">
npm run build:aot && npm run serve:aot
</code-example>
### Inspect the Bundle
It's fascinating to see what the generated JavaScript bundle looks like after Rollup.
The code is minified, so you won't learn much from inspecting the bundle directly.
But the <ahref="https://github.com/danvk/source-map-explorer/blob/master/README.md"target="_blank">source-map-explorer</a>