In this video we will discuss Ahead-of-Time compilation and Just-in-Time compilation in Angular.
In Angular we have 2 models of compilation
- JIT - Just-in-Time Compilation : JIT compilation as the name implies, compiles the application Just-in-Time in the browser at runtime.
- AOT - Ahead-of-Time Compilation : AOT compilation compiles the application at build time.
By default, with the development build we get JIT compilation. This is how it works. The application code along with the angular compiler is downloaded by the browser. At run-time, when a request is issued to the application, the JIT-compiler in the browser compiles the application code before it is executed. This means our user who made that first request has to wait for the application to compile first.
In our previous videos we have seen that, when we build our angular application, the following JavaScript bundles are generated.
- Inline
- Main
- Polyfills
- Styles
- Vendor
There is a tool called source-map-explorer that we can use to inspect the JavaScript bundles. This tool analyzes the source map generated with the bundle and draws a map of all dependencies.
To be able to use this tool we have to install it first. To install this tool, execute the following command
npm install source-map-explorer --save-dev
Once we have the tool installed, if you have not done the development build yet, do the development build using the following command.
ng build
Once the build is complete, you will have the JavaScript bundles along with the source map files. Now execute the following command.
node_modules\.bin\source-map-explorer dist\vendor.bundle.js
The above command runs the source-map-explorer against the vendor bundle and we see the graph of it as shown below. Notice the angular compiler is around 45% percent of the bundle size. As this is development build and not optimised, notice the total size of the bundle is 2.19 MB.
With AOT compilation the angular application is pre-compiled. So this means the browser loads executable code so it can render the application immediately, without waiting to compile the application first.
This also mean with AOT, as the application is already pre-compiled, there is also no need for the browser to download the Angular compiler. As we already know, the compiler code is roughly half of the Angular framework, so omitting it dramatically reduces the application size.
By default, the production build is Ahead-of-Time compiled. So there is no need to bundle up the angular compiler code in the vendor bundle. This brings down the vendor bundle size by almost 50%. In addition it is also minified, uglified and tree-shaked to remove any code that we are not referencing in our application. So the bundler size is further reduced.
Now, execute the following command to generate a production build. Notice I have also turned on sourcemap option. Without the sourcemap we will not be able to use the source-map-explorer tool.
ng build --prod --sourcemap true
Once the production build is complete, execute the following command. Vendor bundle name in your production build may be slightly different. Change it accordingly and execute the command.
node_modules\.bin\source-map-explorer dist\vendor.7e385ef294695236ffd1.bundle.js
Here is the graph produced by the above command. Notice now, we do not have the compiler in the bundle. The bundle size is just 313 KB.
The AOT compiler also detects and reports template binding errors at build time itself. Let us understand this with an example.
Include the following function HomeComponent class in home.component.ts file
getText(): string {
return 'Hello Pragim';
}
In home.component.html include the following <div> element. Notice I have deliberately mis-spelled the getText() function name.
<div [innerText]='getTex()'>
Save changes, and execute the following command. This command does a development build in-memory. At the moment we are not using AOT, so we will not know about the template binding error that is introduced above. Notice at build time we do not see any errors.
ng serve
Now launch your default browser and navigate to http://localhost:4200. We see the "home works" message as expected. However, we do not see the message returned by getText() function. This is because we deliberately mis-spelled the getText() function name. We will see this error in the browser developer tools. So this proves that, with JIT compilation we will only come to know about the template binding errors at runtime.
With AOT compilation, template binding errors are detected and reported at build time itself as apposed to runtime. To prove this, execute the following command. Notice we are using --aot option for pre-compiling our in-memory build.
ng serve --aot
The build completes with the following error. So this proves that, with AOT compilation, template binding errors are detected and reported at build time itself as apposed to runtime
By default, the following 2 commands use JIT compilation
ng build
ng serve
With either of these command we can use --aot option to turn on Ahead-of-Time compilation
ng build --aot
ng serve --aot
The production build uses AOT by default. If you want to turn off AOT for the production build, you can do so by setting --aot option to false as shown below.
ng build --prod --aot false
At this point, we cannot use source-map-explorer to check if the angular compiler is in the vendor bundle because we do not have sourcemap files. If you want to inspect the bundles make sure you also turn on sourcemaps.
0 comments:
Post a Comment
Note: only a member of this blog may post a comment.