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

Fastest SPA in all Mexico: Performance Tuning with Angular

Fastest SPA in all Mexico: Performance Tuning with Angular

Slides from my talk at ploneconf in Barcelona, October 2017

15934fa2aa7b2ce21f091e9b7cffa856?s=128

Manfred Steyer
PRO

October 18, 2017
Tweet

Transcript

  1. Fastest SPA in all Mexico: Angular Performance Tuning

  2. About me… • Manfred Steyer • SOFTWAREarchitekt.at • Trainer &

    Consultant • Focus: Angular • Google Developer Expert (GDE) Page ▪ 3 Manfred Steyer
  3. Turbo Button

  4. Quick Wins Bundling Minification enableProdMode()

  5. Contents • Lazy Loading and Preloading • Performance for Data

    Binding with OnPush • AOT and Tree Shaking • Caching with Service Worker
  6. Lazy Loading

  7. Module Structure Page ▪ 9 AppModule … … … SharedModule

    Root Module Feature Modules Shared Module
  8. Lazy Loading Page ▪ 10 AppModule … … … SharedModule

    Root Module Feature Modules Shared Module
  9. Root Module with Lazy Loading Page ▪ 11 const APP_ROUTE_CONFIG:

    Routes = [ { path: 'home', component: HomeComponent }, { path: 'flights', loadChildren: './[…]flight-booking.module#FlightBookingModule' } ];
  10. Routes for "lazy" Module Page ▪ 12 const FLIGHT_ROUTES =

    [ { path: '', component: FlightBookingComponent, […] }, […] }
  11. Routes for "lazy" Module Page ▪ 13 const FLIGHT_ROUTES =

    [ { path: 'subroute', component: FlightBookingComponent, […] }, […] } flight-booking/subroute Triggers Lazy Loading w/ loadChildren
  12. DEMO

  13. Lazy Loading • Lazy Loading means: Loading it later •

    Better startup performance • Delay during execution for loading on demand
  14. Preloading

  15. Idea • Module that might be needed later are loaded

    after the application started • When module is needed it is available immediately Page ▪ 17
  16. Activate Preloading Page ▪ 18 … imports: [ […] RouterModule.forRoot(

    ROUTE_CONFIG, { preloadingStrategy: PreloadAllModules }); ] …
  17. Performance- Tuning with OnPush

  18. DEMO

  19. OnPush flights flight flight {{ flight.id }} {{ flight.id }}

    FlightSearch Card Card Angular just checks when “notified”
  20. "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 • Trigger it manually • Don't do this at home ;-) • At least: Try to avoid this
  21. Activate OnPush @Component({ […] changeDetection: ChangeDetectionStrategy.OnPush }) export class FlightCard

    { […] @Input() flight; }
  22. Change Inputs flights flight flight {{ flight.id }} {{ flight.id

    }} FlightSearch Card Card flightold === flightnew
  23. Observables and OnPush <flight-card [item]="flight$ | async" […]> </flight-card>

  24. DEMO

  25. Ahead of Time (AOT) Compilation

  26. Angular Compiler HTML Template JavaScript Template Compiler

  27. Approaches • JIT: Just in Time, at runtime • AOT:

    Ahead of Time, during build
  28. Advantages of AOT • Better Startup-Performance • Smaller Bundles: You

    don't need to include the compiler! • Tools can easier analyse the code • Remove not needed parts of frameworks • Tree Shaking
  29. Angular CLI • ng build --prod • @ngtools/webpack with AotPlugin

    • Soon AngularCompilerPlugin • Can be used without CLI too
  30. DEMO

  31. Tree Shaking

  32. Challenges • Most tree shaking tools are conservative • They

    just remove code when they are 100% sure • Very often, they aren't sure :-) • Solution: Angular Build Optimizer • Rewrites compiled code • Currently: Experimental
  33. Sample Application w/ Angular Material

  34. Caching with Service Worker

  35. What are Service Workers? • Background Tasks • Web App

    installs them • Are activated and deactivated on demand
  36. Service Worker und Caching/ Offline • Intercept requests • Decide

    how to respond (Cache, Network) • Same Origin Policy • Caching Patterns • Cache only • Network only • Try cache first, then network • Try network first, then cache • etc.
  37. Angular 5: ServiceWorkerModule

  38. Service Worker with Workbox (sw.js) importScripts('./assets/workbox-sw.js'); const workboxSW = new

    WorkboxSW();
  39. Service Worker with Workbox (sw.js) importScripts('./assets/workbox-sw.js'); const workboxSW = new

    WorkboxSW(); const networkFirst = workboxSW.strategies.networkFirst(); const cacheFirst = workboxSW.strategies.cacheFirst();
  40. Service Worker with Workbox (sw.js) importScripts('./assets/workbox-sw.js'); const workboxSW = new

    WorkboxSW(); const networkFirst = workboxSW.strategies.networkFirst(); const cacheFirst = workboxSW.strategies.cacheFirst(); workboxSW.router.registerRoute( new RegExp('^http:\/\/www.angular.at\/api\/'), networkFirst); workboxSW.router.registerRoute(/./, cacheFirst);
  41. DEMO

  42. Server Side Rendering

  43. Why Server Side Rendering? Prerender 1st Page Start up performance

    Consumer
  44. renderModuleFactory […] renderModuleFactory(moduleFactory, { document: indexFileContentsAsString, url: options.req.url }) .then(string

    => { […] }); […] Available since Angular 4.0
  45. DEMO

  46. Challenges Other conditions Separate Services for Server and Client-Seite Renderer

    abstracts DOM 3rd parts libs Angular 5: Server Side DOM Simulation (partly)
  47. More about this in my Medium Account • Configuration Details,

    Samples etc. • https://medium.com/@ManfredSteyer/angular-performance-tuning- article-series-6e3c33707b25
  48. Conclusion Quick Wins Lazy Loading and Preloading OnPush w/ Immutables

    and Observables AOT and Tree Shaking Caching w/ Service Worker
  49. Contact and Downloads [mail] manfred.steyer@SOFTWAREarchitekt.at [blog] SOFTWAREarchitekt.at [twitter] ManfredSteyer