An Angular code is mainly built with HTML templates and TypeScript code files. If we look into the template structure, there are often used keywords like *ngIf and *ngFor which are structural directives known only to Angular Framework. Even in TypeScript files, Angular depends heavily on decorators like @Component and @Input.
These directives and decorators like many other Angular features are not known to the browser. Then how does our code run smoothly on browsers? This is where Angular Compiler comes in (often referred to as ‘ngc’).
Why Was Angular Compiler Introduced?
Before we started using Angular v2 (or plain Angular), AngularJS didn’t have TypeScript.
AngularJS code was dependent on browsers to create the DOM tree and display the result. But there was a serious problem with this approach. Browsers are inconsistent. Different browsers have different mechanisms to create the DOM tree. They are inconsistent with parsing and handling errors in code. Some browsers might throw an error encountered to the user while some would handle it in their own way by nesting it inside other DOM elements.
What Changed in Angular Compiler after Angular JS?
If you are an Angular developer, you must have seen “Compilation errors” like the following before even going to the browser to check your changes.
This is a layman's example of what has changed.
With Angular versions, came the Angular compiler(ngc) which promised ‘performance’. It was introduced to achieve a minimal memory footprint, faster page load, and quick-change detection.
What Is Angular Compiler and How Does It Work?
Angular Compiler is responsible for compiling (translating) Angular files and libraries. It is built on top of the TypeScript Compiler (referred to as tsc). Along with TypeScript Compiler, the Angular Compiler is able to convert all Angular functionalities into a runtime code that the browser will understand.
- ng serve: Bundled files created in memory. Hence, can’t be used to deploy the code
- ng build: Bundled files are created in a separate folder which is used for deployment..
These files will be embedded in the index.html file which will be then used to execute the code in the browser. This phenomenon is called Bundling
Angular Provides Two Modes of Compilation:
JIT (Just-in-Time) Compilation
AOT (Ahead-of-Time) Compilation
If you are using Angular v9 or above, your application is compiled through AOT by default. While for v8 and below, JIT is the default compilation.
There are two ways to change the mode:
By adding “aot” key in the angular.json file
- Using aot flag with compilation commands:
a. ng serve —aot=true
b. ng build —aot=true
What Is JIT?
JIT compilation is a method of compilation during the execution of a program (at run time). As the compilation is handled at run time, the browser requires bundling of compiler along with source file to run the code.
How Does JIT Work?
Instead of interpreting bytecode each time a method is called, JIT compiles the bytecode into the machine code instructions of the running machine and stores it and then invokes this object code instead.
This means that in JIT, all the code is not converted into machine code at once. Only the code that is used immediately will be converted into machine code. If a method is called which is not in the machine code, then that will also be turned into machine code and stored. This reduces the burden on the CPU and makes the app render faster because it only uses what is needed.
'Source-map-explorer’ is a npm package that can be used to detect which files in each byte of the compiled code came from. When we use this package on the output of JIT Compilation:
Notice the size of the Compiler is about 46.7% (~45%) of the bundle size.
What is AOT?
AOT compilation is the method of compiling the Angular code before the execution of a program i.e., at build-time, to reduce the amount of work needed to be performed at run time and cut down the memory consumption of compiler output.
This means that any compilation failures can be handled before your code reaches the browser.
Let’s look at the bundle size of the AOT compilation result:
Notice that the AOT compilation reduced the JIT Output size from 2 MB to 319 kB.
How Does AOT Work?
AOT Compilation happens in three steps:
Code AnalysisHere the compiler performs an analysis of Angular features like @Component() and @Input(). One of the most important outputs of this phase is ‘.d.ts’ files and ‘.metadata.json’ files which are used later on in the creation of the component and its structure. Any metadata syntax violation errors are fetched and stored during this step.
Code GenerationIn this step, the compiler interprets the files from the first step and checks the semantics of the metadata according to the compiler rules. Metadata is also rewritten. It changes es6 code into a form that is easier to understand for the compiler.
Template Type CheckingAs the name suggests, here the compiler will type-check expressions in the templates to prevent crashes at runtime. The compiler also takes help from the TypeScript compiler to check binding expressions in templates. When any type errors are detected, error messages are produced for the developer.
Difference between the Two:
Why Is Jit Better for Development?
We can easily implement new features and debug in JIT compilation as it provides a map file while AOT does not. Hence code development time is reduced in JIT.
Why Is Aot Better for Production?
This can be proven by these stats from Jeff Cross that show how AOT significantly reduces the time to load and bootstrap the app.
AOT offers significant improvements to load time by reducing the bundle size that is sent to the browser, and by doing the majority of compilation work at build time instead of in the browser. You can use AOT very easily, regardless of the build system. AOT provides an efficient way of compiling your Angular code that results in robust, secure, and lean applications.
If you’re still using JIT, take this article as a sign to shift to AOT and decrease load time significantly.
Fast-growing tech companies partner with Encora to outsource product development and drive growth. Contact us to learn more about our software engineering capabilities.