Angular-Apps with Ivy
×
The rise of a new engine
Expectations
What you cannot expect
- Best practices with Angular in general
- Enterprise Architecture
@MartinaKraus11
What you can expect
- Deep dive in the functionality of the Angular compiler
- Learning about the benefits of Ivy
- Developing Ivy Apps
- Dealing with old packages
GDE in Angular
Women Techmakers Ambassador
Trainer and Consultant
@MartinaKraus11
That's Me
Martina Kraus
martinakraus
@MartinaKraus11
Schedule
@MartinaKraus11
13:30 - 15:00
15:30 - 16:45
15:00 - 15:30
Part 1: Ivy as an enabler
Coffee break
Part 2: Libraries with Ivy
Requirements for Hands On
@MartinaKraus11
-
Node.js
-
Angular.CLI (Angular >= 8.x)
-
Google Chrome
-
Code Editor
Material
@MartinaKraus11
Example Repo and exercises:
http://bit.ly/angular-days-ivy
Slides:
http://bit.ly/slides-mk-ivy
Why support Ivy ? 🤔
How can we benefit from Ivy?
@MartinaKraus11
-
Better build times, thanks to incremental compilation
-
Smaller and faster bundles
-
Sets the ground for lazy-loading components
-
Is easy to debug
-
Introduces new non-zone.js based change detection
-
Uses higher-order components
Default since version 9
@MartinaKraus11
tsconfig.json
//to Opt-out:
"angularCompilerOptions": {
"enableIvy": false
}
Why do we need a compiler?
Compiler in Angular?
@MartinaKraus11
Angular
declarative Code
ngc
JavaScript Code
Compiler in Angular?
@MartinaKraus11
ngc
@Component({ selector: ‘app-component’ template: `<h1>{{ title }}</h1>` }) export class AppCmp {}
JavaScript Code
Compiler in Angular?
@MartinaKraus11
export class AppCmp { title: string; ngComponentDef = ng.defineComponent( {...}) }
ngc
@Component({ selector: ‘app-component’ template: `<h1>{{ title }}</h1>` }) export class AppCmp {}
Other features
@MartinaKraus11
-
Scoping (ngModules)
-
Evaluation of
-
Property chains
-
Variables / function calls
-
Type checking
-
Part 1: Enable Ivy
@MartinaKraus11
Smaller
Faster Compilation
Easier to debug
Ivy as enabler
Part 1: Enable Ivy
@MartinaKraus11
Smaller
Faster Compilation
Easier to debug
Ivy as enabler
Part 1: Enable Ivy
@MartinaKraus11
Let's compile!
@MartinaKraus11
> ng new awesome-app
> ngc
Let's compile!
@MartinaKraus11
// 11.2.4
> ng new awesome-app
> ngc
ViewEngine:
1,4MB
Ivy:
14kB
DEMO
View Engine
@MartinaKraus11
app.cmp.ts
app.cmp.html
app.cmp.scss
app.cmp.js
app.cmp.ngFactory.js
app.cmp.metadata.json
app.cmp.ngsummary.json
Ivy
@MartinaKraus11
app.cmp.ts
app.cmp.html
app.cmp.scss
app.cmp.js
ViewEngine is not Tree-Shakable
Tree Shaking
@MartinaKraus11
Tree shaking is a term commonly used for dead-code elimination in the JavaScript Context.
It relies on the static structure of module syntax.
Takes place during the compilation of the Angular app
ViewEngine: Template compilation
@MartinaKraus11
ViewEngine: Template compilation
@MartinaKraus11
ViewEngine: Template compilation
@MartinaKraus11
@MartinaKraus11
HTML Template
Data
Template
Angular Interpreter
DOM
ViewEngine: Rendering pipeline
@MartinaKraus11
And the Ivy way?
export function elementStart()
export function text()
Ivy instructions
Unsused Code
export function pipe()
@MartinaKraus11
HTML Template
Template instructions
DOM
Ivy rendering pipeline
@MartinaKraus11
Angular-Apps
Others
Delta.com: 4.2MB
Forbes.com: 5.7MB
Android Messages: 1.1MB
Grubhub: 3.4MB
microsoft.com is 1.4MB
amazon.com is 7.5MB
Wikipedia pages are 223KB
reddit.com is 4.9MB
netflix.com is 4.2MB
twitter.com is 3.5MB
Stephen Fluin - https://fluin.io/blog/is-my-angular-performance-normal
Typical bundle size
@MartinaKraus11
angular.json
Budgets
Part 1: Enable Ivy
@MartinaKraus11
Smaller
Faster Compilation
Easier to debug
Ivy as enabler
Single file compilation
@MartinaKraus11
static ɵcmp = core.ɵɵdefineComponent({…})
app.component.js
ViewEngine
@MartinaKraus11
Ivy
@MartinaKraus11
defineDirective
@MartinaKraus11
Locality principle
@MartinaKraus11
Component has all information for being compiled
No global compilation anymore
Ivy provides stable API to ship code through npm
Modules already AOT
Part 1: Enable Ivy
@MartinaKraus11
Smaller
Faster Compilation
Easier to debug
Ivy as enabler
The new 'ng'-Object
@MartinaKraus11
Ivy runtime offers a new ng object for debugging Angular apps, when you run in Dev mode.
This ng object can be accessed in the Developer console of Google Chrome
Offers different Entry Points to access and modify a component and its dependencies
DEMO
@MartinaKraus11
Simpler stack traces
Part 1: Enable Ivy
@MartinaKraus11
Smaller
Faster Compilation
Easier to debug
Ivy as enabler
New ways of writing Angular Apps
@MartinaKraus11
Lazy loading components
Higher Order Components
Zoneless
change detection
Lazy loading components
@MartinaKraus11
Lazy loading components
@MartinaKraus11
ComponentFactoryResolver
Lazy loading components
@MartinaKraus11
ViewContainerRef
Injector
Lazy loading components
@MartinaKraus11
Exercise #1
New ways of writing Angular Apps
@MartinaKraus11
Lazy loading components
Higher Order Components
Zoneless
change detection
ComponentDefinition
@MartinaKraus11
ComponentDefinition
@MartinaKraus11
Higher-Order Component
@MartinaKraus11
DEMO
The future
@MartinaKraus11
Modifying component traits at runtime
(Automatically unsubscribing/ subscribing, changing styles)
More dynamic
Every Ivy component is a standalone component
New ways of writing Angular Apps
@MartinaKraus11
Lazy loading components
Higher Order Components
Zoneless
change detection
Zones.js
@MartinaKraus11
Hard dependency of every Angular Application
"zone.js": "~0.10.2"
NgZone triggers the change detection automatically
Takes care of all event handlers and data bindings
The issue about Zones
@MartinaKraus11
More than 100kB
many performance issues
(long cd cycles together with frequent browser events)
too much magic
Zone-less Change Detection
@MartinaKraus11
Ivy has been defined without considering Zone.js
markDirty
@MartinaKraus11
Calling Angular to check data Binding with Ivy Instruction
markDirty
@MartinaKraus11
Exercise #2
Part 2:
Angular Libraries with Ivy
The issues of compiling Angular projects
@MartinaKraus11
Compiling Angular projects
@MartinaKraus11
The Code that will be compiled with Ivy uses the ngtsc compiler
Libraries, npm modules, other dependencies are already precompiled
- incompatible to the way ngtsc compiles Angular code
- Angular team provides the compatibility compiler
Angular Compatibility Compiler (ngcc)
Compatibility Compiler
@MartinaKraus11
ngcc scans node_modules and produces Ivy-compatible versions of each package
detects the Angular Package Format (APF) and searches
for .metadata.json file and the package's entrypoint
creates output directory ngcc_node_modules (default)
Angular Package Format
@MartinaKraus11
- Describes structure and format of the package available on npm
- Provides entrypoints for several module definitions:
- ESM5
- ES2015
- Universal Module Definition
- Libraries that don't use the APF aren't processed properly with ngcc
- ngcc tries to produce a "wrapper" file
Compatibility Compiler
@MartinaKraus11
copied
copied
converted
Example: Decorators
@MartinaKraus11
@MartinaKraus11
- The ngcc uses the TypeScript parser to parse the compiled js code
-
producing a partial class using JS AST
-
extract the static property definition from the partial class
Example: Decorators
Ok, what about the Libs now?
Angular Libs with Ivy
@MartinaKraus11
Using Libraries
Lib author
Using incompatible Libraries
Entrypoints failure
@MartinaKraus11
#1: Error: Failed to compile entry-point <packagename> due to compilation errors: node_modules/<packagename>/bundles/filename.umd.js(1034,34)]
The issue:
ngcc wasn't able to find a proper entrypoint for converting instructions nor able to create wrapper files
Possible solution (1)
@MartinaKraus11
- Make sure your dependency is on the latest version
- Provide configuration to modify how ngcc views entry-points to packages:
- Giving metadata information for ngcc to find the correct files
- Provided inside a ngcc.config.js file at the root of the package
Example ngcc.config.js
@MartinaKraus11
@MartinaKraus11
- Create a ngcc configuration for the compiler to ignore it
- create your own wrapper classes and patch files
- Remove the package from your dependencies
- Try to avoid dependencies not following the APF
- Open a PR for the Library maintainer
Possible solution (2)
Angular Libraries as an Author
The transition plan
The transition plan
@MartinaKraus11
Recommendation for lib authors
@MartinaKraus11
- You need to publish View Engine AOT-compiled Angular libs
- Additionally publish AOT-compiled libraries for version > 10
Libraries can be compiled ahead-of-time and be published as such to NPM, GitHub Packages etc.
Supporting both compiler
@MartinaKraus11
- Using Git tags or branches to divide the code
- To support differences between View Engine and Ivy we can use detection logic
- can be used to detect ivy components, ivy directives etc.
Angular Ivy detection
@MartinaKraus11
Ivy issues and breaking changes
Injectable Decorator
@MartinaKraus11
Token without @Injectable decorator were allowed if other decorator was used
All provided or injected tokens must have @Injectable decorator
ViewEngine
Ivy
@ContentChildren
@MartinaKraus11
Queries search any nested level in the DOM
Queries will only search direct chield nodes in DOM hierarchy
ViewEngine
Ivy
Injection tokens
@MartinaKraus11
Instance of TemplateRef, ViewContainerRef (and other special tokens) were shared on the same node
Requesting TemplateRef, ViewContainerRef (and other special tokens) return a new instance.
ViewEngine
Ivy
Element references
@MartinaKraus11
Accessing inputs through local refs are not longer support by default
Renderer to Renderer 2
@MartinaKraus11
- Renderer has been marked as deprecated since version 4
- removed in version 9
- default migration for angular apps migrating to version 9
- Library maintainer need to run this migration
Many more:
https://angular.io/guide/ivy-compatibility
Prepare your library for ngcc
@MartinaKraus11
The compatibility compiler can require some changes to your library
- Use the ngcc validation project by the Angular team
- https://github.com/angular/ngcc-validation
Provide your libraries in a proper Angular Package Format ...
... or with proper entrypoint configuration
Angular Package Format:
Do I need to add EVERYTHING manually?
ng-packagr
@MartinaKraus11
ng-packagr transpiles your libraries to Angular Package Format
>>npm install -D ng-packagr
DEMO
@MartinaKraus11
Features:
- Implements APF
- can be consumed by Angular CLI, Webpack ...
- creates type definitions
- Inlines templated and Stylesheets
https://github.com/ng-packagr/ng-packagr/blob/master/README.md
ng-packagr
@MartinaKraus11
Ivy is an enabler: (For more dynamic applications)
- Lazy-loading components
- Higher-Order Components
- optional ngModules/ ngZone
Lib: support differences between both compilers
make sure you follow the Angular Package Format (ng-packagr)
Summary
me@martina-kraus.io
@MartinaKraus11
martina-kraus.io
Slides: http://bit.ly/slides-mk-ivy
Thank you !!!
Ivy
By Martina Kraus
Ivy
Angular Ivy Deep dive with handson
- 734