39
20.10.2016 1 ManfredSteyer Über mich … Manfred Steyer SOFTWAREarchitekt.at Trainer & Consultant GDE & MVP Focus: Angular 2 Page 3 ManfredSteyer

Datenbindung und Performance in Angular 2

Embed Size (px)

Citation preview

Page 1: Datenbindung und Performance in Angular 2

20.10.2016

1

ManfredSteyer

Über mich …

• Manfred Steyer

• SOFTWAREarchitekt.at

• Trainer & Consultant

• GDE & MVP

• Focus: Angular 2

Page 3

ManfredSteyer

Page 2: Datenbindung und Performance in Angular 2

20.10.2016

2

Ziele

• Wie funktioniert die Datenbindung in Angular 2?

• Wie kann man die Performance für Datenbindung verbessern?• Immutables

• Observables

Nicht-Ziele

• Allgemeine Einführung in Angular 2

Page 3: Datenbindung und Performance in Angular 2

20.10.2016

3

Didaktik

• 1. Abschnitt• Präsentation

• Live-Coding

• 2. Abschnitt• Übung mit Übungsblatt und Starterkit

Inhalt• Überblick zur Datenbindung in Angular 2

• Datenbindung hinter den Kulissen

• Two-Way-Binding

• Überblick zu Immutables

• Performancetuning mit Immutables

• Überblick zu Observables

• Performancetuning mit Observables

• Übung

• Bonus: Ausblick auf AOT-Kompilierung

Page 4: Datenbindung und Performance in Angular 2

20.10.2016

4

Benchmark

Überblick zur Datenbindung in Angular 2

Page 5: Datenbindung und Performance in Angular 2

20.10.2016

5

Angular-2-Anwendungen sind Komponenten

Page 12

@Component({selector: 'flight-search',templateUrl: 'flight-search.html'

})export class FlightSearchComponent {

from: string;to: string;flights: Array<Flight>;

constructor(http: Http) { }

search() { [...] }select(flight: Flight) { [...] }

}

Page 13

<input [(ngModel)]="from"><input [(ngModel)]="to">

<button [disabled]="!from || !to" (click)="search()">Search

</button>

<table><tr *ngFor="let f of flights">

<td>{{f.id}}</td><td>{{f.date}}</td><td>{{f.from}}</td><td>{{f.to}}</td>

</tr></table>

Template

Page 6: Datenbindung und Performance in Angular 2

20.10.2016

6

Hinter den Kulissen

Page 14

Architektur-Ziele von Angular 2

Page 15

Performance Komponenten Vorhersagbarkeit

Page 7: Datenbindung und Performance in Angular 2

20.10.2016

7

Data-Binding in AngularJS 1.x

Page 16

Model Model Directive

Komponentne-Baum in Angular 2

Page 17

Komponente für gesamte App

Komponente (z. B. list)

Komponente

(z. B. list-item)

Komponente

(z. B. list-item)

Page 8: Datenbindung und Performance in Angular 2

20.10.2016

8

Regeln für Property Bindings

• Komponente hängt nur von Daten des Parents ab

• Komponente hängt nie von Daten der Kinder ab

• Abhängigkeits-Graph is ein Baum

• Angular benötigt nur eine einzige Iteration („digest“) zum Abgleich des Baumes

Page 18

Property-Binding

Page 19

model

item item

{{ item.title }} {{ item.title }}

[http://victorsavkin.com/post/110170125256/change-detection-in-angular-2]

Page 9: Datenbindung und Performance in Angular 2

20.10.2016

9

Event-Bindings (One-Way, Bottom/Up)

Page 20

{{ item.title }} {{ item.title }}

Event-Handler

Event-Handler

Event-Bindings (One-Way, Bottom/Up)

• Kein Digest nötig

• Event-Handler == Callbacks

• Aber: Events können Anwendungszustand verändern Digest um Property-Bindings zu aktualisieren

Page 21

Page 10: Datenbindung und Performance in Angular 2

20.10.2016

10

Property- und Event-Bindings

Page 22

Property-Bindings

ausführen

Event-Handler warden

ausgeführt

Ereignis tritt ein

Anwendung ist bereit!

Alle Handler ausgeführt

Properties gebunden

Bindings definieren

Page 23

Page 11: Datenbindung und Performance in Angular 2

20.10.2016

11

View

Page 24

<button (click)="search()" [disabled]="!from || !to">Search</button>

<table>

<tr *ngFor="let flight of flights">

<td>{{flight.id}}</td>

<td>{{flight.date}}</td>

<td>{{flight.from}}</td>

<td>{{flight.to}}</td>

<td><a href="#" (click)="selectFlight(flight)">Select</a></td>

</tr>

</table>

<td [text-content]="flight.id"></td>

Recap

• Property-Binding: One-Way; Top/Down

• Event-Binding: One-Way; Bottom/Up

• Two-Way-Binding?

• Two-Way = Property-Binding + Event-Binding

Page 25

Page 12: Datenbindung und Performance in Angular 2

20.10.2016

12

Property- und Event-Bindings kombinieren

Page 26

<input [ngModel]="from" (ngModelChange)="updateFrom($event)">

updateFrom(newValue) {

this.from = newValue;

}

Property- und Event-Bindings kombinieren

Page 27

<input [ngModel]="from" (ngModelChange)="from = $event">

Page 13: Datenbindung und Performance in Angular 2

20.10.2016

13

Syntax-Zucker für Two-Way-Binding

Page 28

<input [(ngModel)]="from">

Vorteile

• Performance

• Events: Flexibilität

• Syntaxzucker: Einfache Nutzung

Page 29

Page 14: Datenbindung und Performance in Angular 2

20.10.2016

14

DEMO: Two-Way-Binding

Page 30

Beispiel: flight-card

Page 31

Page 15: Datenbindung und Performance in Angular 2

20.10.2016

15

Einsatz der flight-card

Page 32

<div *ngFor="let f of flights">

<flight-card [item]="f"

[selectedItem]="selectedFlight"

(selectedItemChange)="selectedFlight = $event">

</flight-card>

</div>

flight-card

Page 33

flug-carditem

selectedItem

>

> > selectedItemChange

flug

selectedFlug

Page 16: Datenbindung und Performance in Angular 2

20.10.2016

16

Beispiel: flight-card

@Component({selector: 'flight-card',templateUrl: './flight-card.component.html'

})export class FlightCard {

@Input() item;@Input() selectedItem;@Output() selectedItemChange = new EventEmitter();

select() {this.selectedItemChange.emit(this.item);

}}

Template<div style="padding:20px;"

[ngStyle]="{'background-color': (selectedItem == item) ? 'orange' : 'lightsteelblue' }" >

<h2>{{item.from}} - {{item.to}}</h2><p>Flugnr. #{{item.id}}</p><p>Datum: {{item.date}}</p>

<p><button class="btn btn-default"

(click)="select()">Select

</button></p>

</div>

Page 17: Datenbindung und Performance in Angular 2

20.10.2016

17

DEMO

Performance-Tuning mit Immutables

Page 18: Datenbindung und Performance in Angular 2

20.10.2016

18

Angular traversiert standardmäßig den gesamten Komponenten-Baum

flights

flight flight

{{ flight.id }} {{ flight.id }}

FlightSearch

Card Card

Immutables

• Unveränderbare Objekte

• Wenn sich repräsentierte Daten ändern: Neues Objekt erzeugen

• Man kann einfach herausfinden, ob sich etwas geändert hat• oldObject == newObject

• Mit oder ohne Bibliotheken möglich (wie immutable.js)

Page 19: Datenbindung und Performance in Angular 2

20.10.2016

19

Beispiel

const ONE_MINUTE = 1000 * 60;

let oldFlights = this.flights;

let oldFlight = oldFlights[0]; // Flight to change!

let oldFlightDate = new Date(oldFlight.date); // Date to change

Änderung ohne Immutables

date.setTime(date.getTime() + ONE_MINUTE * 15);

this.flights[0].date = date.toISOString();

Page 20: Datenbindung und Performance in Angular 2

20.10.2016

20

Änderung mit Immutables

let newFlightDate = new Date(oldFlightDate.getTime() + ONE_MINUTE * 15);

let newFlight = {

id: oldFlight.id,

from: oldFlight.from,

to: oldFlight.to,

date: newFlightDate.toISOString()

};

let newFlights = [

newFlight,

...oldFlights.slice(1, this.flights.length)

];

this.flights = newFlights;

Auf Änderungen prüfen

console.debug("Array: " + (oldFlights == newFlights)); // false

console.debug("#0: " + (oldFlights[0] == newFlights[0])); // false

console.debug("#1: " + (oldFlights[1] == newFlights[1])); // true

Page 21: Datenbindung und Performance in Angular 2

20.10.2016

21

Immutables und Angular 2

• Annahme: Jedes @Input() einer Komponente ist immutable

• Angular kann einfach prüfen, ob sich eingehende Daten einer Komponente ändern

• Nur wenn das der Fall ist, müssen Komponente und deren Kind-Komponenten betrachtetet werden

Immutables und Angular

flights

flight flight

{{ flight.id }} {{ flight.id }}

FlightSearch

Card Card

Änderung

Page 22: Datenbindung und Performance in Angular 2

20.10.2016

22

Optimierung aktivieren

@Component({[…]changeDetection: ChangeDetectionStrategy.OnPush

})export class FlightCard {

[…]@Input flight;

}

DEMO

Page 23: Datenbindung und Performance in Angular 2

20.10.2016

23

Weitere Vorteile von Immutables

• Vereinfacht Nachvollziehbarkeit und Testing -> Kein Zustand

• Vereinfacht Undo/Redo

Observables

Page 24: Datenbindung und Performance in Angular 2

20.10.2016

24

Was sind Observables?

• Repräsentieren asynchrone Daten, die im Verlauf der Zeit veröffentlicht werden

Observer„Senke“

Observable„Quelle“

Operator(z. B. map)

Page 25: Datenbindung und Performance in Angular 2

20.10.2016

25

Observable

Observable

.subscribe((result) => { … },(error) => { … },() => { … }

);

Observer

Beispiel

this.http.get("http://www.angular.at/api/...").map(resp => resp.json()).subscribe(

(flights) => { … },(err) => { console.error(err); }

);

Page 26: Datenbindung und Performance in Angular 2

20.10.2016

26

Eigenes Observable

var observable = Observable.create((sender) => {

sender.next(4711);sender.next(815);

//sender.error("err!");

sender.complete();

});

Asynchron, Ereignis-gesteuert

var subscription = observable.subscribe(…);

subscription.unsubscribe();

return () => { console.debug('Bye bye'); };

Cold vs. Hot Observables

Page 55

Cold

• Standard

• Punkt zu Punkt

• Pro Empfänger ein Sender

• Sender startet erst bei

Anmeldung

Hot

• Punkt zu Multipunkt

• Sender startet auch ohne

Anmeldungen

Page 27: Datenbindung und Performance in Angular 2

20.10.2016

27

Hot Observable

Page 56

var o = Observable.create((observer) => {

observer.next(42);observer.error("err!");

}).publish().connect();

Subjects

Subject

.subscribe((result) => { … },(error) => { … },() => { … }

);

Observer

Daten/ Benachrichtigungvon außen

Page 28: Datenbindung und Performance in Angular 2

20.10.2016

28

Subjects

Page 58

SubjectHot & verteilt

empfangene Daten

BehaviorSubjectSpeichert letzten

Wert

ReplaySubjectSpeichert mehrere

Werte

Performanceoptimierung mit Observables

Page 29: Datenbindung und Performance in Angular 2

20.10.2016

29

Performance und Observables

• Observable benachrichtigt über Datenänderungen

• Datenbindung wird bei Benachrichtigung aktiv

• Aktivierung: OnPush

Observables mit OnPush

Page 61

flights

flight$ flight$

{{ flight$.id }} {{ flight$.id }}

FlightSearch

Card Card

Änderung

Page 30: Datenbindung und Performance in Angular 2

20.10.2016

30

Observables mit OnPush

Page 62

flights$

flight flight

{{ flight.id }} {{ flight.id }}

FlightSearch

Card

Änderung

Card

Observable binden

<flight-card

[item]="flight | async" […]>

</flight-card>

Page 31: Datenbindung und Performance in Angular 2

20.10.2016

31

DEMO

Nicht „Alles-oder-Nichts“

• Optimierungen mit Immutables und Observables funktionieren nicht nach dem „Alles-oder-Nichts“-Prinzip

• Sie können bei Bedarf genutzt werden

Page 32: Datenbindung und Performance in Angular 2

20.10.2016

32

DEMO

Fazit

• Property-Bindings: Top/Down, One-Way

• Event-Bindings: Bottom/Up, One-Way

• 2-Way-Bindings: Property-Binding + Event-Binding

• Architektur: „Fast by default“

• Wer mehr Performance benötigt: Immutables und Observables

Page 33: Datenbindung und Performance in Angular 2

20.10.2016

33

Kontakt

[mail] [email protected]

[web] SOFTWAREarchitekt.at

[twitter] ManfredSteyer

Bonus: AOT-Kompilierung

Page 34: Datenbindung und Performance in Angular 2

20.10.2016

34

Zusätzliche Performance

HTML

TemplateJavaScript

Template Compiler

input['value'] = flight['date'] input.value = flight.date;

Ansätze für das Kompilieren von Templates

• JIT: Just im Time, zur Laufzeit

• AOT: Ahead of Time, beim Build

Page 35: Datenbindung und Performance in Angular 2

20.10.2016

35

Vorteile von AOT

• Bessere Startup-Performance

• Kleinere Bundles: Compiler für JIT muss nicht ausgeliefert werden

• Bessere statische Analysierbarkeit des Programmcodes

HTML

TypeScript

TypeScript

Angular 2

Tree Shaking

Page 36: Datenbindung und Performance in Angular 2

20.10.2016

36

Installation des AOT-Compilers (ngc)

• npm install @angular/compiler-cli --save-dev

• npm install [email protected] --save-dev

• npm install @angular/platform-server --save

Page 78

tsconfig.aot.json

• module: ES2015

• Target: ES2015

Page 79

"angularCompilerOptions": {

"genDir": "aot",

"skipMetadataEmit" : true

}

Page 37: Datenbindung und Performance in Angular 2

20.10.2016

37

webpack2

• UglifyJsPlugin

• LoaderOptionsPlugin

• --optimize-minimize

Page 80

Kompilieren

• ngc -p tsconfig.aot.json

Page 81

Page 38: Datenbindung und Performance in Angular 2

20.10.2016

38

Bootstrapping

Page 82

import { platformBrowser } from '@angular/platform-browser';import { AppModuleNgFactory } from './app.module.ngfactory';

platformBrowser().bootstrapModuleFactory(AppModuleNgFactory);

DEMO

Page 39: Datenbindung und Performance in Angular 2

20.10.2016

39

Fazit

• Hohes Potential (Performance, Bundle-Größe, Tree-Shaking)

• Sehr junges Feature

• Tooling entsteht gerade (z. B. Integration in WebPack)

• Wird wohl erst ab Version 2.1 „runde Sache“

Kontakt

[mail] [email protected]

[web] SOFTWAREarchitekt.at

[twitter] ManfredSteyer