Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Angular Performance Tuning - State of affairs (...

Angular Performance Tuning - State of affairs (Director's Cut)

My Talk from BASTA! Spring 2018 in Frankfurt, Germany

Source Code:
https://github.com/manfredsteyer/basta-spring-2018-angular-performance

Blog:
http://www.softwarearchitekt.at

Avatar for Manfred Steyer

Manfred Steyer

February 21, 2018
Tweet

More Decks by Manfred Steyer

Other Decks in Programming

Transcript

  1. @BASTAcon & @ManfredSteyer About me… • Manfred Steyer • SOFTWAREarchitekt.at

    • Angular Trainings and Consultancy • Google Developer Expert (GDE) • Microsoft MVP Page ▪ 3 Manfred Steyer
  2. @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
  3. @BASTAcon & @ManfredSteyer Module Structure Page ▪ 8 AppModule …

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

    … … SharedModule Root Module Feature Modules Shared Module
  5. @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' } ];
  6. @BASTAcon & @ManfredSteyer Routes for "lazy" Module Page ▪ 11

    const FLIGHT_ROUTES = [ { path: '', component: FlightBookingComponent, […] }, […] }
  7. @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
  8. @BASTAcon & @ManfredSteyer Activate Preloading Page ▪ 17 … imports:

    [ […] RouterModule.forRoot( ROUTE_CONFIG, { preloadingStrategy: PreloadAllModules }); ] …
  9. @BASTAcon & @ManfredSteyer OnPush flights flight flight {{ flight.id }}

    {{ flight.id }} FlightSearch Card Card Angular just checks when “notified”
  10. @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
  11. @BASTAcon & @ManfredSteyer Approaches • JIT: Just in Time, at

    runtime • AOT: Ahead of Time, during build
  12. @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
  13. @BASTAcon & @ManfredSteyer Angular CLI • ng build --prod •

    @ngtools/webpack with AngularCompilerPlugin • Can be used without CLI too
  14. @BASTAcon & @ManfredSteyer Getting rid of zone.js (since Angular 5)

    • Consequence: You need to do change detection manually • Not fun ;-) Don't do this (carelessly)! • Ideas to solve this, e. g. observable$ | somePipe • Credits to Jeremy Wilken from the Angular Universal Team • Dreams of the (near) future? platformBrowserDynamic().bootstrapModule(AppModule, { ngZone: 'noop' })
  15. @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!
  16. @BASTAcon & @ManfredSteyer Global Providers (nowadays) @NgModule([ […], providers: [

    { provide: Service, useClass: AdvancedService } ] ]) export class MyModule { } Not treeshakable!
  17. @BASTAcon & @ManfredSteyer Option in v6 @Injectable({ scope: MyModule, useClass:

    AdvancedService }) export class Service { } Option / No braking change!
  18. @BASTAcon & @ManfredSteyer Further improvements in upcoming versions New View

    Engine ngIvy: More treeshakable Code No Breaking Changes "Early numbers are extremely promising in terms of code size" -- Rob Wormald Experimental with Angular 6
  19. @BASTAcon & @ManfredSteyer Google Closure Compiler Aggressive Optimizations E2E-Test necessary

    Expert Tool Difficult to configure! Office 365 Google Docs, etc.
  20. @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!");
  21. @BASTAcon & @ManfredSteyer ABC • Angular • Bazel = Build

    Tool • Closure = Optimizing Compiler • Angular Labs Project == Experimental
  22. @BASTAcon & @ManfredSteyer Import Operators import 'rxjs/add/operator/map'; // Patch Observable

    --> add map import 'rxjs/add/operator/filter'; this.http.get<Flight>(url) .filter(f => f.price < 300) .map(f => toFlightOffer(f)) .subscribe(…); Not treeshakable!
  23. @BASTAcon & @ManfredSteyer Better Alternative: Pipeable Operators this.http.get<Flight>(url) .pipe( filter(f

    => f.price < 300), map(f => toFlightOffer(f)) ) .subscribe(…); import { map, filter } 'rxjs/operators';
  24. @BASTAcon & @ManfredSteyer Removing Whitespaces <p> Hello</p> <p>World! </p> \n

    //Pseudo Code createNode('p', ' Hello World'); createNode('TEXT-NODE', '\n'); createNode('p', 'World!'); Template Compiler
  25. @BASTAcon & @ManfredSteyer Removing Whitespaces <p> Hello</p> <p>World! </p> \n

    //Pseudo Code createNode('p', ' Hello World'); createNode('TEXT-NODE', '\n'); createNode('p', 'World!'); Template Compiler
  26. @BASTAcon & @ManfredSteyer Removing Whitespaces @Component({ selector: 'flight-card', templateUrl: './flight-card.component.html',

    styleUrls: ['./flight-card.component.css'], preserveWhitespaces: false }) export class FlightCardComponent { […] }
  27. @BASTAcon & @ManfredSteyer Switching it on globally in tsconfig.app.json […]

    "angularCompilerOptions": { "preserveWhitespaces": false } […]
  28. @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)
  29. @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!
  30. @BASTAcon & @ManfredSteyer More about this in my Medium Account

    • Configuration Details, Samples, Videos etc. • https://medium.com/@ManfredSteyer/angular-performance-tuning- article-series-6e3c33707b25