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

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

  1. Using Git tags or branches to divide the code
  2. 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