Slide 1

Slide 1 text

Real-World Angular Erfahrungen aus (fast) vier Jahren Projektgeschäft Christian Liebel @christianliebel Consultant

Slide 2

Slide 2 text

The image part with relationship ID rId3 was not found in the file. The image part with relationship ID rId3 was not found in the file. The image part with relationship ID rId3 was not found in the file. Special Day “Modern Business Applications” Thema Sprecher Datum, Uhrzeit Raum Pragmatische Microservices-Architekturen mit .NET Core – Patterns und Code Christian Weyer DI, 26. Februar 2019, 10.30 bis 11.30 Ballsaal 2 Serverless-Architekturen: Event-basierte Microservices mit Azure Functions und Co. Christian Weyer DI, 26. Februar 2019, 11.45 bis 12.45 Ballsaal 2 Real-World Angular: Erfahrungen aus (fast) vier Jahren Projektgeschäft Christian Liebel DI, 26. Februar 2019, 14.15 bis 15.15 Ballsaal 2 Progressive Enhancement im Web: PWA-Grundlagen Sebastian Springer DI, 26. Februar 2019, 15.30 bis 16.30 Gold 3 PWA Deep Dive: Offlineanwendungen im Griff Christian Liebel DI, 26. Februar 2019, 17.15 bis 18.15 Gold 3

Slide 3

Slide 3 text

Hello, it’s me. Real-World Angular Erfahrungen aus (fast) vier Jahren Projektgeschäft Christian Liebel Follow me: @christianliebel Blog: christianliebel.com Email: christian.liebel @thinktecture.com Cross-Platform & Cloud & Enterprise Blockchain

Slide 4

Slide 4 text

Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular

Slide 5

Slide 5 text

Promises & Observables TypeScript Packages & Modules Component Libraries Performance Cross- Platform Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Talking Points

Slide 6

Slide 6 text

Promises & Observables TypeScript Packages & Modules Component Libraries Performance Cross- Platform Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Talking Points

Slide 7

Slide 7 text

Promises vs. Observables Promise (.NET: Task) - wraps an async task - one result - eager execution - not cancellable (exception: abort signals, see Fetch API) - async/await keywords - Native ECMAScript feature async get(url) { const r = await fetch(url); return await r.json(); } Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Promises & Observables

Slide 8

Slide 8 text

Promises vs. Observables RxJS/Observables (.NET: Reactive Extensions) - wraps an async task - one or multiple results - lazy execution - cancellable - operators for high-level flow composition - Library get(url) { return obsFetch(url).pipe( switchMap(r => r.json()) ); } get('https://foo.com') .subscribe(); Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Promises & Observables

Slide 9

Slide 9 text

Observables - Angular heavily relies on RxJS and Observables - Reactive programming is extremely powerful - Even complex operations can be implemented by using only a few lines of code - But: RxJS has a steep learning curve, as it’s a completely different discipline of programming - RxJS has 80+ operators - You have to unsubscribe from long-lived observables, otherwise: Memory leak! Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Promises & Observables

Slide 10

Slide 10 text

Observables - Your developer team should learn RxJS! - https://www.learnrxjs.io - https://rxjs.dev/operator-decision-tree - Prefer Observables over Promises - Avoid subscribing to Observables yourself - Services should not subscribe to Observables. - Let the framework subscribe for you and use the async pipe to use Observables/Promises in a synchronous manner Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Promises & Observables

Slide 11

Slide 11 text

Demo Use Case - Master/detail app - The detail route should take an ID parameter - Fetch the given ID from the server - If it fails, retry it three times with a delay of one second Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Promises & Observables LIVE DEMO

Slide 12

Slide 12 text

Promises & Observables TypeScript Packages & Modules Component Libraries Performance Cross- Platform Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Talking Points

Slide 13

Slide 13 text

ECMAScript Language Versions After ECMAScript 5 (2009), there was a long break in JavaScript development that lasted until ECMAScript 2015 (6) Since then, a new ECMAScript version is released every year (typically with a small set of changes) Sources: - http://2ality.com/ - https://github.com/tc39/proposals Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular TypeScript

Slide 14

Slide 14 text

ECMAScript Feature Stages 0 1 2 3 4 STRAWMAN PROPOSAL DRAFT CANDIDATE FINISHED Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular TypeScript BigInt

Slide 15

Slide 15 text

Language Features Fat-Arrow Functions () => doSomething(); Destructuring Expressions const { clientX, clientY } = event; Exponentation operator 2 ** 3 Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular TypeScript

Slide 16

Slide 16 text

Language Features TypeScript Compiler is a source-to-source transpiler (target: JavaScript of a given version) TypeScript allows using opt-in static typing Additionally, TypeScript allows you to use (some) Stage 3 features and transpiles them to code understandable by older JavaScript engines (downlevel support). Use TypeScript to write the JavaScript of the future today! Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular TypeScript

Slide 17

Slide 17 text

Compiler Switches TypeScript has different strict type checking options. Examples: --noImplicitAny --strictNullChecks --strictPropertyInitialization Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular TypeScript LIVE DEMO

Slide 18

Slide 18 text

Compiler Switches Common Pitfalls - every TS file must obey the strict type checking options, including all third-party libraries - --strict enables all strict type checking options, even future ones you might not know of today! Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular TypeScript

Slide 19

Slide 19 text

unknown vs. any any is the most-capable type - and thus the most dangerous one - opt-out of TypeScript checks & warnings unknown is the least-capable type - suitable for API borders or libraries without type definitions - first check which type it could be, then use it Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular TypeScript LIVE DEMO

Slide 20

Slide 20 text

Promises & Observables TypeScript Packages & Modules Component Libraries Performance Cross- Platform Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Talking Points

Slide 21

Slide 21 text

Project Structure Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Packages & Modules Git Repositories CLI Projects NgModules

Slide 22

Slide 22 text

Everything in one module Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Packages & Modules 1 Git Repository 1 CLI Project 1 NgModule

Slide 23

Slide 23 text

Modularization 1 Git Repository 1 CLI Project CoreModule CalculationModule AppModule Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Packages & Modules

Slide 24

Slide 24 text

Monorepo Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Packages & Modules 1 Git Repository Library Project CoreModule CalculationModule App Project AppModule

Slide 25

Slide 25 text

Monorepo ng new myProject --createApplication=false ng generate library myLib ng generate application myApp Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Packages & Modules LIVE DEMO

Slide 26

Slide 26 text

Multiple Repositories Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Packages & Modules Library Repository Library Project CoreModule CalculationModule App Repository App Project AppModule

Slide 27

Slide 27 text

Monorepo Monorepo - Easier to maintain - Not isolated - Suitable when everything is released at the same time (see Angular) Multiple Repositories - More complex to maintain - Isolated - Suitable when implementations have to be independent from each other Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Packages & Modules

Slide 28

Slide 28 text

Promises & Observables TypeScript Packages & Modules Component Libraries Performance Cross- Platform Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Talking Points

Slide 29

Slide 29 text

Make all vs. Buy all Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Component Libraries Make all Buy all

Slide 30

Slide 30 text

Make all - Implement event handling, styling & co. yourself - Maximum customization (best for use case) - Maximum effort (keyboard, cross-browser testing, performance, a11y) - No external/recurring costs - Best for projects with highly specific use cases Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Component Libraries Make all Buy all

Slide 31

Slide 31 text

Buy all - DevExpress, PrimeNG, ag-Grid, Angular Material, … - Limited customization & predefined styling (Bootstrap) - Minimum effort - (Hopefully) battle-tested (keyboard, cross-browser testing, …) - External/recurring costs - Best for projects with limited budget, time and/or general use cases Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Component Libraries Make all Buy all

Slide 32

Slide 32 text

Angular CDK - Unstyled base functionality for components (Drag and Drop, overlays, tree, table, …) - Battle-tested (keyboard, cross-browser testing, performance, a11y) - Open-source - Best for projects with general use cases and custom styling - https://material.angular.io/cdk/ Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Component Libraries Make all Buy all

Slide 33

Slide 33 text

Angular CDK a node another node Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Component Libraries LIVE DEMO

Slide 34

Slide 34 text

Promises & Observables TypeScript Packages & Modules Component Libraries Performance Cross- Platform Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Talking Points

Slide 35

Slide 35 text

In general - Reduce amount of computations, layouts, paints, … In Angular - Mostly related to Change Detection Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Performance

Slide 36

Slide 36 text

Zone.js Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Performance current (global) zone NgZone Angular boot

Slide 37

Slide 37 text

A Meta-Monkey Patch Performance setTimeout setInterval geolocation.getCurrentPosition XMLHttpRequest PromiseRejectionEvent requestAnimationFrame click focus mousemove addEventListener Real-World Angular Erfahrungen aus (fast) vier Jahren Projektgeschäft

Slide 38

Slide 38 text

In Angular Applications - Reduce amount of change detection cycles - Disable zone - NgZone - Zone.js patches - ChangeDetectorRef - ChangeDetectionStrategy - Reduce duration of change detection cycle Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Performance

Slide 39

Slide 39 text

Disable zone (= disable async change detection!) platformBrowserDynamic().bootstrapModule(AppModule, { ngZone: 'noop' }); constructor(applicationRef: ApplicationRef) { applicationRef.tick(); // trigger CD yourself } Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Performance

Slide 40

Slide 40 text

Reduce amount of change detection cycles Run performance critical code (mousemove/scroll event listeners, requestAnimationFrame, short setIntervals) outside Angular’s zone Remember: Change detection is turned off! constructor(private _zone: NgZone) {} this._zone.runOutsideAngular(() => performanceCritical().then( () => this._zone.run(() => this.foo = 123) )); Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Performance

Slide 41

Slide 41 text

Reduce amount of change detection cycles Turn off Zone patches in general (see polyfills.ts) (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Performance

Slide 42

Slide 42 text

Reduce amount of change detection cycles @Component({ template: '{{ foo }}', changeDetection: ChangeDetectionStrategy.OnPush }) export class MyComponent { @Input() // detect after change of input only! public foo: string; constructor(cdRef: ChangeDetectorRef) { cdRef.markForCheck(); } } Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Performance

Slide 43

Slide 43 text

Reduce amount of change detection cycles constructor(cdRef: ChangeDetectorRef) { cdRef.detach(); // detaches this view from the CD tree // cdRef.detectChanges(); // detect this view & children // cdRef.reattach(); } Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Performance

Slide 44

Slide 44 text

Reduce amount of change detection duration - Reduce amount of bindings - Avoid binding to (computationally intensive) getters Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Performance

Slide 45

Slide 45 text

Profiling platformBrowserDynamic().bootstrapModule(AppModule).then(module => { const [appComponent] = module.injector.get(ApplicationRef).components; enableDebugTools(appComponent); }); Execute ng.profiler.timeChangeDetection() to measure the duration of a change detection run Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Performance

Slide 46

Slide 46 text

Promises & Observables TypeScript Packages & Modules Component Libraries Performance Cross- Platform Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Talking Points

Slide 47

Slide 47 text

Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Cross-Platform

Slide 48

Slide 48 text

Tools - Ionic - focus on mobile - NativeScript - focus on mobile - mixes Angular (e.g. service logic) with native UI controls - Cordova/Electron - Progressive Web Apps Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Cross-Platform

Slide 49

Slide 49 text

Apache Cordova/GitHub Electron Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Cross-Platform Result: App packages .ipa, .apk, .appx Result: Executables .exe, .app, ELF

Slide 50

Slide 50 text

Progressive Web App Erfahrungen aus (fast) vier Jahren Projektgeschäft Real-World Angular Cross-Platform • No app stores anymore! • Web App = App App • Feature parity: Push notifications, offline availability and more for web & native applications • Backwards compatibility: PWAs can also be run on non-PWA browsers, but with reduced feature set

Slide 51

Slide 51 text

Thank you for your kind attention! Christian Liebel @christianliebel [email protected]