02.07.2016 1 Databinding and Performance-Tuning in Angular 2 Manfred Steyer Contents • How databinding works • How to improve performance with Immutables and Observables
02.07.2016 2 About me … • Manfred Steyer • SOFTWAREarchitekt.at • Trainer & Consultant • Focus: Angular Page  3 Manfred Steyer Bindings in Angular 2 Page  4
02.07.2016 3 Some Goals of Angular 2 Page  5 Performance Components Predictability Data-Binding in Angular 1.x Page  6 Model Model Directive Nearly everything can depend on everything Solution: Multiple Digest-Cycles
02.07.2016 4 Component-Tree in Angular 2 Page  7 Component for whole App Component (e. g. list) Component (e. g. list-item) Component (e. g. list-item) Rules for Property-Bindings • A Component only depends on its own data (and indirectly on its parents data) • A Component must not depend on its children data! • Dependency Graph is a tree • Angular only needs one iteration („digest“) to update tree Page  9
02.07.2016 5 Property-Binding Page  10 model item item {{ item.title }} {{ item.title }} [http://victorsavkin.com/post/110170125256/change-detection-in-angular-2] Event-Bindings (One-Way, Bottom/Up) Page  14 {{ item.title }} {{ item.title }} Event-Handler Event-Handler
02.07.2016 6 Event-Bindings (One-Way, Bottom/Up) • No Digest-Iterations for propagating events • But: Events can change state  Digest for updating Property-Bindings Page  15 Property- and Event-Bindings Page  17 Performing Property-Binding Executing Event-Handlers Event occurs App is ready All Handlers executed Properties bound
02.07.2016 7 Setting up Bindings Page  18 View Page  20 <button (click)="search()" [disabled]="!from || !to"> <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>
02.07.2016 8 View Page  21 <button on-click="search()" bind-disabled="!from || !to"> <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="#" on-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  22
02.07.2016 9 Combining Property- and Event-Bindings Page  23 <input [ngModel]="from" (ngModelChange)="updateFrom($event)"> updateFrom(newValue) { this.from = newValue; } Combining Property- and Event-Bindings Page  24 <input [ngModel]="from" (ngModelChange)="from = $event">
02.07.2016 10 Syntax-Sugar for „simulating“ Two-Way Page  25 <input [(ngModel)]="from"> <input bindon-ngModel="from"> Performance-Tuning with Immutables and Observables
02.07.2016 11 Angular traverses the whole tree by default flights flight flight {{ flight.id }} {{ flight.id }} FlightSearch Card Card Immutables • Objects that can not change • When represented data changes, they have been replaced by an other immutable • Easy to find out if there was a change • oldObject == newObject • With or without libs (like immutable.js)
02.07.2016 12 Immutables 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 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;
02.07.2016 13 Checking for Change console.debug("Array: " + (oldFlights == newFlights)); // false console.debug("#0: " + (oldFlights[0] == newFlights[0])); // false console.debug("#1: " + (oldFlights[1] == newFlights[1])); // true Immutables and Angular 2 • Data flows top/down • When Angular 2 assumes that every @Input of a component is an immutable it just has to check if they changed • If not: Skip component and every child component (whole sub-tree)
02.07.2016 14 Immutables and Angular flights flight flight {{ flight.id }} {{ flight.id }} FlightSearch Card Card Change How to tell Angular to assume Immutables? @Component({ […] changeDetection: ChangeDetectionStrategy.OnPush }) export class FlightCard { […] @Input flight; }
02.07.2016 15 DEMO Observables mit OnPush Page  41 flights flight$ flight$ {{ flight$.id }} {{ flight$.id }} FlightSearch Card Card Change
02.07.2016 16 Observables mit OnPush Page  42 flights$ flight flight {{ flight.id }} {{ flight.id }} FlightSearch Card Change Card How to bind to an Observable? <flight-card [item]="flight | async" […]> </flight-card>
02.07.2016 17 DEMO Not "all-or-nothing" • Using Immutables and Obersvables isn't an "all-or-nothing- thing" • You can just use for componentes that need additional performance
02.07.2016 18 Contact manfred.steyer@SOFTWAREarchitekt.at SOFTWAREarchitekt.at ManfredSteyer

Databinding and Performance-Tuning in Angular 2

  • 1.
    02.07.2016 1 Databinding and Performance-Tuning in Angular2 Manfred Steyer Contents • How databinding works • How to improve performance with Immutables and Observables
  • 2.
    02.07.2016 2 About me … •Manfred Steyer • SOFTWAREarchitekt.at • Trainer & Consultant • Focus: Angular Page  3 Manfred Steyer Bindings in Angular 2 Page  4
  • 3.
    02.07.2016 3 Some Goals ofAngular 2 Page  5 Performance Components Predictability Data-Binding in Angular 1.x Page  6 Model Model Directive Nearly everything can depend on everything Solution: Multiple Digest-Cycles
  • 4.
    02.07.2016 4 Component-Tree in Angular2 Page  7 Component for whole App Component (e. g. list) Component (e. g. list-item) Component (e. g. list-item) Rules for Property-Bindings • A Component only depends on its own data (and indirectly on its parents data) • A Component must not depend on its children data! • Dependency Graph is a tree • Angular only needs one iteration („digest“) to update tree Page  9
  • 5.
    02.07.2016 5 Property-Binding Page  10 model itemitem {{ item.title }} {{ item.title }} [http://victorsavkin.com/post/110170125256/change-detection-in-angular-2] Event-Bindings (One-Way, Bottom/Up) Page  14 {{ item.title }} {{ item.title }} Event-Handler Event-Handler
  • 6.
    02.07.2016 6 Event-Bindings (One-Way, Bottom/Up) •No Digest-Iterations for propagating events • But: Events can change state  Digest for updating Property-Bindings Page  15 Property- and Event-Bindings Page  17 Performing Property-Binding Executing Event-Handlers Event occurs App is ready All Handlers executed Properties bound
  • 7.
    02.07.2016 7 Setting up Bindings Page 18 View Page  20 <button (click)="search()" [disabled]="!from || !to"> <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>
  • 8.
    02.07.2016 8 View Page  21 <buttonon-click="search()" bind-disabled="!from || !to"> <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="#" on-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  22
  • 9.
    02.07.2016 9 Combining Property- andEvent-Bindings Page  23 <input [ngModel]="from" (ngModelChange)="updateFrom($event)"> updateFrom(newValue) { this.from = newValue; } Combining Property- and Event-Bindings Page  24 <input [ngModel]="from" (ngModelChange)="from = $event">
  • 10.
    02.07.2016 10 Syntax-Sugar for „simulating“Two-Way Page  25 <input [(ngModel)]="from"> <input bindon-ngModel="from"> Performance-Tuning with Immutables and Observables
  • 11.
    02.07.2016 11 Angular traverses thewhole tree by default flights flight flight {{ flight.id }} {{ flight.id }} FlightSearch Card Card Immutables • Objects that can not change • When represented data changes, they have been replaced by an other immutable • Easy to find out if there was a change • oldObject == newObject • With or without libs (like immutable.js)
  • 12.
    02.07.2016 12 Immutables 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 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;
  • 13.
    02.07.2016 13 Checking for Change console.debug("Array:" + (oldFlights == newFlights)); // false console.debug("#0: " + (oldFlights[0] == newFlights[0])); // false console.debug("#1: " + (oldFlights[1] == newFlights[1])); // true Immutables and Angular 2 • Data flows top/down • When Angular 2 assumes that every @Input of a component is an immutable it just has to check if they changed • If not: Skip component and every child component (whole sub-tree)
  • 14.
    02.07.2016 14 Immutables and Angular flights flightflight {{ flight.id }} {{ flight.id }} FlightSearch Card Card Change How to tell Angular to assume Immutables? @Component({ […] changeDetection: ChangeDetectionStrategy.OnPush }) export class FlightCard { […] @Input flight; }
  • 15.
    02.07.2016 15 DEMO Observables mit OnPush Page 41 flights flight$ flight$ {{ flight$.id }} {{ flight$.id }} FlightSearch Card Card Change
  • 16.
    02.07.2016 16 Observables mit OnPush Page 42 flights$ flight flight {{ flight.id }} {{ flight.id }} FlightSearch Card Change Card How to bind to an Observable? <flight-card [item]="flight | async" […]> </flight-card>
  • 17.
    02.07.2016 17 DEMO Not "all-or-nothing" • UsingImmutables and Obersvables isn't an "all-or-nothing- thing" • You can just use for componentes that need additional performance
  • 18.