slides: bit.ly/jsheroes-ivy
Andrei Antal
@andrei_antal
- frontend engineer, since i can remember
- currently doing consulting and training @JSLeague
- web & JS technologies enthusiast
- UX and accessibility passionate
- perpetual learner
Frontend Developer
organizer for ngBucharest
@ngBucharest
groups/angularjs.bucharest
Noh, servus!
Upcoming events
8 - 9 October 2020, Timisoara
Angular 9 is out!
What's new in Angular 9?
- Ivy - now enabled by default in new projects (was opt-in for v8)
- New rendering engine replacing ViewEngine (more on that in just a minute)
- Smaller builds
Smaller bundle sizes
Smaller bundle sizes
Smaller bundle sizes
What's new in Angular 9?
- Ivy - now enabled by default in new projects (was opt-in for v8)
- New rendering engine replacing ViewEngine (more on that in just a minute)
- Smaller builds
- Strict template checking and language service improvements (DEMO)
- New options for providedIn
What's new in Angular 9?
@Injectable({
providedIn: "root" | "any" | "platform"
})
export class MyService {}
What's new in Angular 9?
- Ivy - now enabled by default in new projects (was opt-in for v8)
- New rendering engine replacing ViewEngine (more on that in just a minute)
- Smaller builds
- Strict template checking and language service improvements (DEMO)
- New options for providedIn
- @ViewChild(...{static: false}) not needed - the default
- TypeScript 3.7 support
- Testing improvements (DEMO)
- New in browser debugging capabilities (DEMO)
How to upgrade?
ng update @angular/core @angular/cli
Ivy
Ivy
[brief] History of Angular
-
Angular 2 (2016)
- Renderer v1 - Template Compiler
- NgModules
-
Angular 4 (2017)
- Animations and HttpClient
- Renderer v2 - ViewEngine
-
Angular 8 (2019)
- Diferential loading
- Renderer v3 - Ivy - preview mode
Why a compiler?
Angular templates (declarative)
JavaScript code that runs in the browser
compilation
@Component({
selector: ‘app-component’
template:
'<h1>{{ title }}</h1>'
})
export class AppCmp {
title = "hello";
}
export class AppCmp {
title: string;
ngComponentDef
= ng.defineComponent({...})
}
ngc
- transform Angular abstractions
- create and manipulate DOM
- bindings and change detection
- css and animations
Why a compiler?
Angular Compiler
Angular Runtime
(not shipped with your final bundle when using AOT)
Evolution - Template Compiler
Evolution - ViewEngine
Evolution - Ivy
ViewEngine pipeline
app.component.ts
app.component.html
app.component.(s)css
app.component.js
app.component.ngfactory.js
app.component.metadata.json
app.component.ngsummary.json
ViewEngine compiler
ViewEngine compiler
Tree shaking
// moduleA.js
export function f1() {
...
}
export function f2() {
...
}
// main.js
import { f1 } from './moduleA.js';
f1();
Only f1 is included in the final bundle
// moduleA.js
export function f1() {
...
}
export function f2() {
...
}
// main.js
import { f1 } from './moduleA.js';
f1();
if(condition) {
f2();
}
Both f1 and f2 are included in the bundle
Ivy pipeline
app.component.ts
app.component.html
app.component.(s)css
app.component.js
No more ngfactory files!
Ivy compilation
@Component({
selector: 'app',
template: `<h1>{{title}}</h1>`
})
class AppComponent {
title="Ivy Renderer";
}
var AppComponent = (function () {
AppComponent.ngComponentDef = defineComponent({
type: AppComponent,
selectors: [["app-root"]],
consts: 2,
vars: 1,
template: function AppComponent_Template(renderFlags, ctx) {
if (renderFlags & RenderFlags.Create) {
elementStart(0, "h1");
text(1);
elementEnd();
} if (renderFlags & RenderFlags.Update) {
textBinding(1, interpolation1("", ctx.title, ""));
}
},
encapsulation: 2
});
}());
creation phase
update/change phase
AppComponent.ngComponentDef.template(create, app)
Ivy compilation
AppComponent
UserComponent
WidgetComponent
AppComponent.ngComponentDef.template(create, app)
UserComponent.ngComponentDef.template(create, user)
WidtgetComponent.ngComponentDef.template(create, widget)
Ivy compilation
- Create instructions
element()
text()
template()
elementContainer()
projection()
listener()
pipe()
i18n()
...
- Update instructions
property()
attribute()
styleProp()
classProp()
hostProperty()
pipeBind()
textInterpolate1-8()
pureFunction1-8()
...
Ivy compilation
Ivy compilation
Ivy compilation
Ivy - tree shakable
- Ivy instruction
Angular
export function elementStart() { ... } export function text() { ... } export function attribute() { ... }
elementStart() text() attribute()
- Component definition calls the Framework
// other unused Angular features -> tree-shaken
...
Incremental vs Virtual DOM
- Virtual DOM
Incremental vs Virtual DOM
- Incremental DOM
Locality
- Faster compilation times:
- ViewEngine requires a global static analysis of the entire application
- In Ivy:
- Compiling a component/directive etc. only requires local information
- Recompiling (due to change) should not trigger recompilation of the dependencies
Locality
<div>
<span>{{title}}</span>
<child-component *ngIf="show"></child-component>
</div>
function View_RootCmp_0(_l) {
return ng.ɵvid(0, [
(_l()(), ng.ɵeld(0, 0, null, null, 4, "div", [], null, null, null, null, null)),
(_l()(), ng.ɵeld(1, 0, null, null, 1, "span", [], null, null, null, null, null)),
(_l()(), ng.ɵted(2, null, ["", ""])),
(_l()(), ng.ɵand(16777216, null, null, 1, null, View_RootCmp_1)),
ng.ɵdid(4, 16384, null, 0, ng.NgIf, [ng.ViewContainerRef, ng.TemplateRef], {ngIf: [0, "ngIf"]}, null)
], );
}
ViewEngine - non-locality
Locality
<div>
<span>{{title}}</span>
<child-component *ngIf="show"></child-component>
</div>
function RootCmp_Template(rf, ctx) {
if (rf & 1) {
ng.ɵelementStart(0, "div");
ng.ɵelementStart(1, "span");
ng.ɵtext(2);
ng.ɵelementEnd();
ng.ɵtemplate(3, RootCmp_child_cmp_Template_3, 1, 0, null, [1, "ngIf"]);
ng.ɵelementEnd();
} if (rf & 2) {
ng.ɵtextBinding(2, ng.ɵinterpolation1("",
ctx.title, ""));
ng.ɵelementProperty(3, "ngIf", ng.ɵbind(ctx.show));
}
}
Ivy - locality
NgIf.ngDirectiveDef = i0.ɵdefineDirective({
factory: function NgIf_Factory(t) {
return new NgIf(
i0.ɵinject(ViewContainerRef),
i0.ɵinject(TemplateRef)
);
},
...
});
A look into the future of Angular
WARNING! Experimental APIs
(do try this at home)
Code repo:
Module-less component
and
zone-less change detection
branch: 1-render_single_component
branch: 2-moduless-component-and-zoneless-change-detection
Lazy load components
branch: 3-lazy-load-components
Higher-order components
branch: 4-higher-order-components
Thank you!
JSHeroes - Angular 9 Ivy
By Andrei Antal
JSHeroes - Angular 9 Ivy
A look at Angular Ivy, the new rendering engine in v9. JSHeroes meetup, April 2020
- 2,167