Slide 1

Slide 1 text

@BASTAcon & @ManfredSteyer Performance for Angular New Possibilities and Proven Classics Manfred Steyer SOFTWAREarchitekt.at ManfredSteyer

Slide 2

Slide 2 text

@BASTAcon & @ManfredSteyer About me… • Manfred Steyer • SOFTWAREarchitekt.at • Angular Trainings and Consultancy • Google Developer Expert (GDE) Page ▪ 3 Manfred Steyer Public: Vienna, München, Zürich In-House: everywhere http://softwarearchitekt.at/workshops

Slide 3

Slide 3 text

@BASTAcon & @ManfredSteyer Turbo Button

Slide 4

Slide 4 text

@BASTAcon & @ManfredSteyer Quick Wins Bundling Minification enableProdMode()

Slide 5

Slide 5 text

@BASTAcon & @ManfredSteyer Contents • Lazy Loading • Performance for Data Binding with OnPush • AOT and Tree Shaking • New and upcoming features • Caching with Service Worker • Serverside Rendering

Slide 6

Slide 6 text

@BASTAcon & @ManfredSteyer Lazy Loading

Slide 7

Slide 7 text

@BASTAcon & @ManfredSteyer Module Structure Page ▪ 8 AppModule … … … SharedModule Root Module Feature Modules Shared Module

Slide 8

Slide 8 text

@BASTAcon & @ManfredSteyer Lazy Loading Page ▪ 9 AppModule … … … SharedModule Root Module Feature Modules Shared Module

Slide 9

Slide 9 text

@BASTAcon & @ManfredSteyer Root Module with Lazy Loading Page ▪ 10 const APP_ROUTE_CONFIG: Routes = [ { path: 'home', component: HomeComponent }, { path: 'flights', loadChildren: './[…]flight-booking.module#FlightBookingModule' } ];

Slide 10

Slide 10 text

@BASTAcon & @ManfredSteyer Routes for "lazy" Module Page ▪ 11 const FLIGHT_ROUTES = [ { path: '', component: FlightBookingComponent, […] }, […] }

Slide 11

Slide 11 text

@BASTAcon & @ManfredSteyer DEMO

Slide 12

Slide 12 text

@BASTAcon & @ManfredSteyer Preloading

Slide 13

Slide 13 text

@BASTAcon & @ManfredSteyer Idea • Module that might be needed later are loaded after the application started • When module is needed it is available immediately Page ▪ 16

Slide 14

Slide 14 text

@BASTAcon & @ManfredSteyer Activate Preloading Page ▪ 17 … imports: [ […] RouterModule.forRoot( ROUTE_CONFIG, { preloadingStrategy: PreloadAllModules }); ] …

Slide 15

Slide 15 text

@BASTAcon & @ManfredSteyer Performance- Tuning with OnPush

Slide 16

Slide 16 text

@BASTAcon & @ManfredSteyer DEMO

Slide 17

Slide 17 text

@BASTAcon & @ManfredSteyer OnPush flights flight flight {{ flight.id }} {{ flight.id }} FlightSearch Card Card Angular just checks when “notified”

Slide 18

Slide 18 text

@BASTAcon & @ManfredSteyer "Notify" about change? • Change bound data (@Input) • OnPush: Angular just compares the object reference! • e. g. oldFlight === newFlight • Raise Event within the component • Notify a bound observable • observable$ | async • Trigger it manually • Don't do this at home ;-) • At least: Try to avoid this

Slide 19

Slide 19 text

@BASTAcon & @ManfredSteyer Activate OnPush @Component({ […] changeDetection: ChangeDetectionStrategy.OnPush }) export class FlightCard { […] @Input() flight; }

Slide 20

Slide 20 text

@BASTAcon & @ManfredSteyer DEMO

Slide 21

Slide 21 text

@BASTAcon & @ManfredSteyer Ahead of Time (AOT) Compilation

Slide 22

Slide 22 text

@BASTAcon & @ManfredSteyer Angular Compiler HTML Template JavaScript Template Compiler

Slide 23

Slide 23 text

@BASTAcon & @ManfredSteyer Approaches • JIT: Just in Time, at runtime • AOT: Ahead of Time, during build

Slide 24

Slide 24 text

@BASTAcon & @ManfredSteyer Advantages of AOT • Better Startup-Performance • Smaller Bundles: You don't need to include the compiler! • Tools can easier analyse the code • Remove unneeded parts of frameworks • Tree Shaking

Slide 25

Slide 25 text

@BASTAcon & @ManfredSteyer Angular CLI • ng build --prod • @ngtools/webpack with AngularCompilerPlugin • Can be used without CLI too

Slide 26

Slide 26 text

@BASTAcon & @ManfredSteyer Flight Search (Prod Build w/o AOT) Production Mode without AOT (no lazy loading)

Slide 27

Slide 27 text

@BASTAcon & @ManfredSteyer Production Mode with AOT (no lazy loading)

Slide 28

Slide 28 text

@BASTAcon & @ManfredSteyer Bundles without AOT and Tree Shaking JIT Compiler

Slide 29

Slide 29 text

@BASTAcon & @ManfredSteyer AOT is stricter than JIT !

Slide 30

Slide 30 text

@BASTAcon & @ManfredSteyer Solutions Angular Language Service • Plugins for IDEs AOT for debugging • Possible since Angular 5 • Incremental AOT • Fast after 1st recompilation • ng serve --aot • Give it a try!

Slide 31

Slide 31 text

@BASTAcon & @ManfredSteyer Angular Build Optimizer makes code more treeshakable (default since CLI 1.5)

Slide 32

Slide 32 text

@BASTAcon & @ManfredSteyer Treeshakable Providers >= Angular 6

Slide 33

Slide 33 text

@BASTAcon & @ManfredSteyer Classical Providers @NgModule({ [...] providers: [ FlightService ], [...] }) export class Module { }

Slide 34

Slide 34 text

@BASTAcon & @ManfredSteyer

Slide 35

Slide 35 text

@BASTAcon & @ManfredSteyer Service Page ▪ 39 @Injectable({ providedIn: 'root' }) export class FlugService { […] } Globaler Scope

Slide 36

Slide 36 text

@BASTAcon & @ManfredSteyer Alternative Page ▪ 40 @Injectable({ providedIn: LazyApiModule }) export class FlugService { […] } Macht nur mit Lazy Loading sinn!! Service wird mit lazy Module mitgeladen

Slide 37

Slide 37 text

@BASTAcon & @ManfredSteyer ngIvy Outlook

Slide 38

Slide 38 text

@BASTAcon & @ManfredSteyer Further improvements in upcoming versions New Compiler/ View Engine More treeshakable Code No Breaking Changes Experimental with Angular 6

Slide 39

Slide 39 text

@BASTAcon & @ManfredSteyer

Slide 40

Slide 40 text

@BASTAcon & @ManfredSteyer

Slide 41

Slide 41 text

@BASTAcon & @ManfredSteyer Beyond Tree Shaking

Slide 42

Slide 42 text

@BASTAcon & @ManfredSteyer Google Closure Compiler Aggressive Optimizations E2E-Test necessary Expert Tool Difficult to configure! Office 365 Google Docs, etc.

Slide 43

Slide 43 text

@BASTAcon & @ManfredSteyer Sample class Stuff { static stuff(data: string) { console.log('stuff: ' + data); } } function stuff(data: string) { Stuff.stuff(data); } stuff('Hallo Welt!'); console.log("stuff: Hallo Welt!");

Slide 44

Slide 44 text

@BASTAcon & @ManfredSteyer ABC • Angular • Bazel = Build Tool • Closure = Optimizing Compiler • Angular Labs Project == Experimental

Slide 45

Slide 45 text

@BASTAcon & @ManfredSteyer Removing Whitespaces

Slide 46

Slide 46 text

@BASTAcon & @ManfredSteyer Removing Whitespaces

Hello

World!

Slide 47

Slide 47 text

@BASTAcon & @ManfredSteyer Removing Whitespaces

Hello

World!

\n //Pseudo Code createNode('p', ' Hello World'); createNode('TEXT-NODE', '\n'); createNode('p', 'World!'); Template Compiler

Slide 48

Slide 48 text

@BASTAcon & @ManfredSteyer Removing Whitespaces

Hello

World!

\n //Pseudo Code createNode('p', ' Hello World'); createNode('TEXT-NODE', '\n'); createNode('p', 'World!'); Template Compiler

Slide 49

Slide 49 text

@BASTAcon & @ManfredSteyer Removing Whitespaces @Component({ selector: 'flight-card', templateUrl: './flight-card.component.html', styleUrls: ['./flight-card.component.css'], preserveWhitespaces: false }) export class FlightCardComponent { […] }

Slide 50

Slide 50 text

@BASTAcon & @ManfredSteyer Switching it on globally in tsconfig.app.json […] "angularCompilerOptions": { "preserveWhitespaces": false } […]

Slide 51

Slide 51 text

@BASTAcon & @ManfredSteyer Caching with Service Worker

Slide 52

Slide 52 text

@BASTAcon & @ManfredSteyer Service Worker Browser Service-Worker Anfrage Antwort Cache Same Origin Policy You control this!

Slide 53

Slide 53 text

@BASTAcon & @ManfredSteyer Two possible abstractions for Service Worker @angular/service-worker

Slide 54

Slide 54 text

@BASTAcon & @ManfredSteyer ng add @angular/pwa

Slide 55

Slide 55 text

@BASTAcon & @ManfredSteyer DEMO

Slide 56

Slide 56 text

@BASTAcon & @ManfredSteyer Server Side Rendering

Slide 57

Slide 57 text

@BASTAcon & @ManfredSteyer Why Server Side Rendering? Prerender 1st Page Start up performance Consumer Apps

Slide 58

Slide 58 text

@BASTAcon & @ManfredSteyer renderModuleFactory […] renderModuleFactory(moduleFactory, { document: indexFileContentsAsString, url: options.req.url }) .then(htmlString => { […] }); […] Available since Angular 4.0

Slide 59

Slide 59 text

@BASTAcon & @ManfredSteyer

Slide 60

Slide 60 text

@BASTAcon & @ManfredSteyer Challenges Other conditions Separate Services for Server and Client-Seite Renderer abstracts DOM 3rd parts libs Angular 5: Server Side DOM Simulation (partly)

Slide 61

Slide 61 text

@BASTAcon & @ManfredSteyer Conclusion Quick Wins Lazy Loading and Preloading OnPush w/ Immutables and Observables AOT and Tree Shaking Pipeable Rx-Operators Server Side Rendering Lean back: The ng team takes care!

Slide 62

Slide 62 text

@BASTAcon & @ManfredSteyer More about this in my Medium Account • Configuration Details, Samples, Videos etc. • https://medium.com/@ManfredSteyer/angular-performance-tuning- article-series-6e3c33707b25

Slide 63

Slide 63 text

@BASTAcon & @ManfredSteyer Contact and Downloads [mail] [email protected] [web] SOFTWAREarchitekt.at [twitter] ManfredSteyer d http://softwarearchitekt.at/workshops Slides & Examples