Ivy is the next generation of Angular Renderer. It is third in line after the original compiler (for Angular 2) and Renderer2 (for Angular 4 and above). Misko Hevery and Kara Erickson gave us the first look of Ivy in ngConf-2018.
Words of caution here — Ivy is still in Beta and is not feature complete. So it wont be there in Angular v6 by default but can be enabled for experimentation and testing which is discussed later in the blog.
Below are the questions which we will try to dig into in this post —
- What are the features of Ivy?
- Difference between Renderer2 and Ivy.
- How it works.
- Trying it in a simple project.
So, we must be wondering by now what are the features that Ivy offers. Ivy is going to be smaller, simpler and faster as quoted by angular team. In the demo shown by Misko in ngConf 2018, the Hello World application was merely 3.2KB which is significantly small. Though, 3.2KB is the result after minification + gzip.
Ivy follows the locality principle where only one file is compiled at a time. It only looks at a component and its template, not its dependencies, when generating the output. This leads to faster compilation and simplification of process.
Earlier, with the previous renderer, template code that worked in JIT (just in time) would not compile to AoT (Ahead of time). Since locality has simplified the process, it means that library creators will be able to ship AoT code through NPM registry and we’ll have an equivalence between AoT and JIT.
With locality, there’s more opportunity for meta-programming, like higher order components and the ability to dynamically generate modules, components, or pipes.
Ivy makes sure that, if you’re not using something in Angular, it doesn’t get included. For that it uses more efficient tree-shaking, removing unused pieces of your code, which results in smaller bundles and faster load times. Ivy breaks things down into smaller, more atomic functions. These atomic functions make the renderer code much more friendly to tree-shaking, because they generate only the code you need from the template you’ve written.
Since Ivy pipelining is simplified, templates will be part of the stack trace. No more cryptic error messages when something is broken in our template syntax as we’ll see the exact line number where the error is. We’ll even be able to set breakpoints in our templates to debug them and that will be great for developers.
So, with Ivy we have smaller builds, faster rebuild time, faster development, human readable code, easy to debug code and simpler pipeline.
Comparison between Renderer 2 and Ivy
Renderer 2 is view engine for angular v4 onwards and is quite different from Ivy in ways of compilation and performance. Following are the major difference between both of them.
Renderer2 rendering pipeline:
Currently in Renderer2 pipeline, the template HTML that we’ve written runs through the Angular compiler and generates highly optimised JS code that represents the structure of your template. At runtime, this data structure is passed to the Angular interpreter, which uses the data to determine how to create the DOM.
Ivy rendering pipeline:
Instead of generating template data and passing it into an interpreter that then makes decisions on which operations to run ,we generate a set of template instructions directly. These instructions will do the work of creating the correct DOM on their own. So we no longer need an interpreter that will check whether every operation is needed.
Renderer2 does static analysis of all code and generate a file called metadata.json that could be used to generate the compilation instructions. This template data was then sent to the Angular interpreter in order to be translated into something readable by the DOM. Ivy compresses these steps, and the template HTML is turned into instructions that are then readable by DOM.
Tree Shaking is performed by both Renderer2 and Ivy. But in some cases suppose, we have imported a function and is hidden by some false conditional, but that function will still get included in the bundle, even though it’s never called for renderer 2.
Ivy, on the other hand, breaks things down into smaller, more atomic functions. These atomic functions make the renderer code much more friendly to tree-shaking, because they generate only the code you need from the template you’ve written.
Removing Dependence on Platform-Browser & Greatly simplifying bootstrap code:
Ivy just inlines DOM Renderer to its core. If we only need run to our application on browser, we can run Angular without including platform specific code.
All Angular applications need to configure bootstrap component , and initialize one
NgModule[Factory] but they have simplified bootstrap code and this code is based on component and Ivy is based on NgModule-less bootstrapping.
How Angular Ivy works?
Now we will discuss how ivy works and the compilation process.
Angular has introduced two compiler entry-points,
enableIvyflag is set to true in the tsconfig.json file for the project.
- ngcc (Ng Compatibility Compiler):
ngccis designed to process code coming from NPM modules and produce the equivalent Ivy version, as if the code was compiled with
ngtsc. It will operate given a
node_modulesdirectory and a set of packages to compile, and will produce an equivalent directory from which the Ivy equivalents of those modules can be read.
ngccis a separate script entry point to
Ivy Compilation Model
In Ivy model, Angular decorators (
@Injectable, etc) are compiled to static properties on the classes (
ngInjectableDef). This process takes place without complete analysis of code, and in most cases with a decorator only. Here, the only exception is
@Component, which requires knowledge of the meta-data from the
@NgModule which declares the component in order to properly generate the
ngComponentDef. The selectors which are applicable during compilation of a component template are determined by the module that declares that component.
The information needed by Reference Inversion and type-checking is included in the type declaration of the
ngComponentDef in the
.d.ts. Here, Reference Inversion is process of determining list of the components, directives, and pipes on which the decorator(which is getting compiled ) depends allowing the module to be ignored altogether
This is the model by which Angular code will be compiled, shipped to NPM, and eventually bundled into applications.
For example, the following class declaration:
The above code will be emitted as following by ngtsc:
Trying Ivy in sample project.
Ivy is still in Beta phase and is not feature complete and it has still a long way before ready for production. So, for now we will try Ivy with small app.
1. Update angular-cli and nodeJs with respective compatible version supporting Angular 6 packages
2. Create a project with minimal files. Use Command: $ ng new ivy-demo –minimal
3. Add enableIvy to src/tsconfig.app.json
4. Remove BrowserModule from AppModule and use NgModule-less bootstrapping.
5. Simplify AppComponent
6. Add ngc script to package.json
7. Set target: es2016 in tsconfig.json
8. Run ngc.Use command- yarn ngc -p src/tsconfig.app.json
9. The outputs are in tsc-out directory.
10. Open tsc-out/app/src/app/app.component.js and there are ngComponentDef and ngInjectorDef.
Here AppComponent.ngComponentDef and AppModule.ngInjectorDef are component and injector definition using Ivy APIs and template function is generated from the components’ HTML template.
Below is the github link:
Since Ivy is not feature complete , we can know the status on:
Simultaneously published at https://blog.imaginea.com/ivy-a-look-at-the-new-render-engine-for-angular/