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

Angular-Performance: So zünden Sie den Turbo

Angular-Performance: So zünden Sie den Turbo

Was in zwei Sekunden nicht lädt, wird nie wieder aufgerufen: Die Erwartung von Anwendern an die Performance von Webanwendungen nimmt stetig zu. Und auch nach dem Laden einer Webanwendung muss sich diese schnell und flüssig anfühlen, damit der Anwender sein Ziel erreichen kann. Mit Zones, Change-Detection- und Preloading-Strategien, Lazy Loading, Ahead-of-time-Kompilierung und Service Workern stehen in Angular verschiedene Techniken zur Verfügung, um selbst große Webanwendungen super schnell auszuführen. Christian Liebel von Thinktecture zeigt Ihnen die Stellschrauben des Frameworks, damit Sie auch für Ihre Angular-App den Turbo zünden können.

Christian Liebel

March 20, 2019
Tweet

More Decks by Christian Liebel

Other Decks in Programming

Transcript

  1. What you cannot expect - Web performance in general (e.g.

    HTTP/2, compression, JS tweaks, CSS) - Deep-dive into performance metrics What you can expect - Angular-specific performance measures - Common performance pitfalls and how to avoid them - Hands-on exercies for everyone Angular Performance So zünden Sie den Turbo Expectations
  2. Hello, it’s me. Angular Performance So zünden Sie den Turbo

    Christian Liebel Follow me: @christianliebel Blog: christianliebel.com Email: christian.liebel @thinktecture.com Cross-Platform & Cloud & Enterprise Blockchain
  3. Angular Performance So zünden Sie den Turbo Timetable 13:30–15:00 Part

    I 15:00–15:30 Coffee break 15:30–17:00 Part II
  4. Setup complete? (Node.js + Angular CLI + Google Chrome +

    Editor) Angular Performance So zünden Sie den Turbo
  5. 53% der Benutzer springen ab, wenn eine Website länger lädt

    als 3 Sekunden. (DoubleClick, Google) Für jede Sekunde Ladezeit springen je 10% der Benutzer ab. (BBC) Bessere Performance = geringere Absprungrate Angular Performance So zünden Sie den Turbo
  6. Runtime Performance Bundling Lazy Loading Preloading Strategies Server-Side Rendering Service

    Worker Angular Performance So zünden Sie den Turbo Agenda Change Detection Basics Zone.js & NgZone Change Detection Strategies Change Detector Async Pipe Load Time Performance
  7. Reduce required computations during runtime - calculations - painting -

    layouting - … Today: Angular-specific performance topics Angular Performance So zünden Sie den Turbo Runtime Performance
  8. Runtime Performance Bundling Lazy Loading Preloading Strategies Server-Side Rendering Service

    Worker Angular Performance So zünden Sie den Turbo Agenda Change Detection Basics Zone.js & NgZone Change Detection Strategies Change Detector Async Pipe Load Time Performance
  9. Hi Angular! Basics // app.component.html <h1>Hi {{ title }}!</h1> //

    app.component.ts @Component({ /* … */ }) export class AppComponent { title = 'Angular'; } Angular Performance So zünden Sie den Turbo Change Detection
  10. Basics // app.component.html <h1>Hi {{ title }}!</h1> <button (click)="update()"> Update

    </button> // app.component.ts @Component({ /* … */ }) export class AppComponent { title = 'Angular'; update() { this.title = 'Foo'; } } Angular Performance So zünden Sie den Turbo Change Detection Hi Foo! Hi Angular! Update
  11. Basics Change detection… - is the magical part of Angular

    that makes data binding “just work” - is a very handy feature that helps a lot, but it can also work against you - is strongly related to Angular application performance Angular Performance So zünden Sie den Turbo Change Detection
  12. Change Detector Tree AppComponent NavComponent ContentComponent ListComponent Angular Performance So

    zünden Sie den Turbo Change Detection AppComponent CD NavComponent CD ContentComponent CD ListComponent CD CHANGE
  13. Change Detector detectChanges() Called when an event has occured and

    bindings should be checked Angular Performance So zünden Sie den Turbo Change Detection this.title = 'Foo'; <h1>Hi {{ title }}!</h1>
  14. Per default, each change in your application leads to… -

    A single CD cycle - From top to bottom (all components) - Unidirectional (no cycles allowed) Angular Performance So zünden Sie den Turbo Change Detection DEMO
  15. First findings Reduce duration of a change detection cycle -

    Reduce amount of bindings (e.g. grids: virtual scrolling via CDK) - Avoid binding to (computationally intensive) getters or functions Keep CD cycle < 16 ms! Angular Performance So zünden Sie den Turbo Change Detection
  16. Profiling // main.ts platformBrowserDynamic().bootstrapModule(AppModule).then(module => enableDebugTools(module.injector.get(ApplicationRef).components[0])); Execute ng.profiler.timeChangeDetection() to measure

    the duration of a change detection run (500ms or 5 change detection cycles) Angular Performance So zünden Sie den Turbo Change Detection
  17. Command Line: ng new perf-demo // src/main.ts platformBrowserDynamic().bootstrapModule(AppModule).then(module => enableDebugTools(module.injector.get(ApplicationRef).components[0]));

    DevTools Console: ng.profiler.timeChangeDetection() Angular Performance So zünden Sie den Turbo Change Detection EX #1
  18. Runtime Performance Bundling Lazy Loading Preloading Strategies Server-Side Rendering Service

    Worker Angular Performance So zünden Sie den Turbo Agenda Change Detection Basics Zone.js & NgZone Change Detection Strategies Change Detector Async Pipe Load Time Performance
  19. How to detect a change? AppComponent NavComponent ContentComponent ListComponent Angular

    Performance So zünden Sie den Turbo Zone.js AppComponent CD NavComponent CD ContentComponent CD ListComponent CD CHANGE
  20. A look at Angular’s dependencies "dependencies": { "@angular/common": "~7.2.0", "core-js":

    "^2.5.4", "rxjs": "~6.3.3", "zone.js": "~0.8.26" }, Zone.js So zünden Sie den Turbo Angular Performance
  21. Overview Provided by the Angular team Open-source https://github.com/angular/zone.js 1. Provides

    an execution context for asynchronous JavaScript 2. A meta-monkey patch Zone.js So zünden Sie den Turbo Angular Performance
  22. Execution Context function main() { // const start = performance.now();

    a(); setTimeout(b, 0); c(); // const stop = performance.now(); // const ms = stop - start; } Zone.js So zünden Sie den Turbo Angular Performance
  23. Execution Context Oversimplified Zone.run(main); onZoneEnter(); function main() { a(); setTimeout(b,

    0); c(); } onZoneLeave(); Zone.js const orig = window.setTimeout; window.setTimeout = (c, t) => { orig(() => { onZoneEnter(); c(); onZoneLeave(); }, t); }; So zünden Sie den Turbo Angular Performance
  24. Execution Context Debugging Pending asynchronous tasks are known Profiling Measuring

    performance (Google Web Tracing Framework) Mocking/Testing Hooks beforeTask, … Zone.js So zünden Sie den Turbo Angular Performance
  25. NgZone NgZone catches asynchronous operations from the Angular app When

    no tasks are remaining for the current VM turn, the NgZone will trigger a change detection cycle (tick) Angular Performance So zünden Sie den Turbo Zone.js NgZone setTimeout setInterval onclick Detect changes Detect changes Detect changes
  26. Change Detection Trigger https://github.com/angular/angular/blob/master/packages/core/src/application_ref.ts Angular Performance So zünden Sie den

    Turbo Zone.js NgZone.onMicrotaskEmpty ApplicationRef.tick() view1.detectChanges() view2.detectChanges() viewN.detectChanges()
  27. Common Pitfalls Long CD cycles in combination with high-frequency events

    - mousemove - scroll - requestAnimationFrame - setInterval with short intervals (clocks!) Angular Performance So zünden Sie den Turbo Zone.js DEMO
  28. NgZone Zone.js current (global) zone NgZone rAF Detect changes rAF

    Detect changes rAF Detect changes rAF Detect changes So zünden Sie den Turbo Angular Performance
  29. NgZone Opt-Out constructor (ngZone: NgZone) { ngZone.runOutsideAngular(() => { //

    runs outside Angular zone, for performance-critical code ngZone.run(() => { // runs inside Angular zone, for updating view afterwards }); }); } Zone.js So zünden Sie den Turbo Angular Performance ! View and model can get out of sync!
  30. NgZone Opt-Out // app.component.ts get title() { console.log('CD'); return 'title';

    } ngOnInit() { requestAnimationFrame(() => this.ngOnInit()); // this._ngZone.runOutsideAngular(() => request…); } constructor(private _ngZone: NgZone) {} Angular Performance So zünden Sie den Turbo Zone.js EX #2
  31. NgZone Zone.js current (global) zone NgZone rAF rAF rAF rAF

    So zünden Sie den Turbo Angular Performance
  32. Disable Patches (polyfills.ts) (window as any).__Zone_disable_requestAnimationFrame = true; // disable

    patch requestAnimationFrame (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames Angular Performance So zünden Sie den Turbo Zone.js ! View and model can get out of sync!
  33. Disable Zone (= disable async change detection!) platformBrowserDynamic().bootstrapModule(AppModule, { ngZone:

    'noop' }); constructor(applicationRef: ApplicationRef) { applicationRef.tick(); // trigger CD yourself } Angular Performance So zünden Sie den Turbo Zone.js ! View and model can get out of sync!
  34. Runtime Performance Bundling Lazy Loading Preloading Strategies Server-Side Rendering Service

    Worker Angular Performance So zünden Sie den Turbo Agenda Change Detection Basics Zone.js & NgZone Change Detection Strategies Change Detector Async Pipe Load Time Performance
  35. Overview Default Uses Zone.js for detecting changes and updates bindings

    OnPush Restricts change detection to changes of @Input parameters Angular Performance So zünden Sie den Turbo Change Detection Strategies AppComponent CD NavComponent CD ContentComponent CD ListComponent CD AppComponent CD NavComponent CD ContentComponent CD ListComponent CD OnPush
  36. OnPush <my-component [foo]="bar"> </my-component> @Component({ selector: 'my-component', template: '{{ foo

    }}', changeDetection: ChangeDetectionStrategy.OnPush }) export class MyComponent { @Input() public foo: string; } Change detection only reacts to changes of @Input parameters Angular compares the values passed to an @Input parameter (newValue === oldValue). If you are passing objects, make sure to pass in new instances! Angular Performance So zünden Sie den Turbo Change Detection Strategies ! View and model can get out of sync! DEMO
  37. Immutable.js to the rescue Immutable.js is a library that does

    not update data in place, but yields updated data instead https://facebook.github.io/immutable-js/ const map1 = Immutable.Map({ a: 1, b: 2, c: 3 }); const map2 = map1.set('b', 50); map1.get('b'); // 2 map2.get('b'); // 50 map2.toObject(); // { a: 1, b: 50, c: 3 } Change Detection Strategies So zünden Sie den Turbo Angular Performance
  38. // app.component.ts @Component({ changeDetection: ChangeDetectionStrategy.OnPush }) /* … */ ngOnInit()

    { requestAnimationFrame(() => this.ngOnInit()); // this._ngZone.runOutsideAngular(() => request…); } Angular Performance So zünden Sie den Turbo Change Detection Strategies EX #3
  39. Runtime Performance Bundling Lazy Loading Preloading Strategies Server-Side Rendering Service

    Worker Angular Performance So zünden Sie den Turbo Agenda Change Detection Basics Zone.js & NgZone Change Detection Strategies Change Detector Async Pipe Load Time Performance
  40. OnPush & Detecting Changes What to do if a component

    changes unrelated to an @Input parameter? constructor(private dataService: DataService) {} ngOnInit() { this.dataService.updates$ .subscribe(newData => this.data = newData); // no update! } Angular Performance So zünden Sie den Turbo Change Detector
  41. ChangeDetectorRef constructor(cdRef: ChangeDetectorRef) {} A reference to the ChangeDetector of

    your component - detectChanges() - markForCheck() - detach() - checkNoChanges() - reattach() Angular Performance So zünden Sie den Turbo Change Detector
  42. markForCheck() Explicitly marks a component as dirty/changed (when using OnPush)

    Angular Performance So zünden Sie den Turbo Change Detector AppComponent CD NavComponent CD ContentComponent CD ListComponent CD DIRTY AppComponent CD NavComponent CD ContentComponent CD ListComponent CD OnPush
  43. markForCheck() constructor(private dataService: DataService, private cdRef: ChangeDetectorRef) {} ngOnInit() {

    this.dataService.updates$.subscribe(newData => { this.data = newData; this.cdRef.markForCheck(); }); } Angular Performance So zünden Sie den Turbo Change Detector
  44. Detaching Components changeDetector.detach(); changeDetector.reattach(); Angular Performance So zünden Sie den

    Turbo Change Detector AppComponent CD NavComponent CD ContentComponent CD ListComponent CD AppComponent CD NavComponent CD ContentComponent CD ListComponent CD ! View and model can get out of sync!
  45. Local Change Detection constructor(cdRef: ChangeDetectorRef) { cdRef.detach(); // detaches this

    view from the CD tree // cdRef.detectChanges(); // detect this view & children // cdRef.reattach(); } Angular Performance So zünden Sie den Turbo Change Detector
  46. Detaching components ng g c test Use <app-test></app-test> in app.component.html

    // test.component.ts title = 'test'; constructor(public cdRef: ChangeDetectorRef) { cdRef.detach(); } // test.component.html <button (click)="cdRef.detectChanges()"></button> {{ title }} Angular Performance So zünden Sie den Turbo Change Detector EX #4
  47. Findings Reduce amount of change detection cycles - Disable Zone.js

    (not a good idea in most cases) - Opt-out of NgZone (for operations that should not affect bindings) - Disable Zone.js patches (in case you can’t opt-out, e.g. 3rd party libs) - ChangeDetectionStrategy.OnPush (good default, but be careful) - Local change detection via ChangeDetectorRef (for the few components that do not have to respond to changes from outside) Angular Performance So zünden Sie den Turbo Change Detector
  48. Runtime Performance Bundling Lazy Loading Preloading Strategies Server-Side Rendering Service

    Worker Angular Performance So zünden Sie den Turbo Agenda Change Detection Basics Zone.js & NgZone Change Detection Strategies Change Detector Async Pipe Load Time Performance
  49. Overview Takes observables, promises or synchronous values {{ data$ |

    async }} Waits for the observable to emit/promise to resolve and then displays the value Angular Performance So zünden Sie den Turbo Async Pipe
  50. Advantages For observables: - Async Pipe subscribes for you -

    Async Pipe takes care of unsubscribing from the observable - Async Pipe calls markForCheck for each update – perfect match for OnPush! https://github.com/angular/angular/blob/master/packages/common/src/pipes/async_pipe.ts Angular Performance So zünden Sie den Turbo Async Pipe
  51. Simplifying OnPush constructor(private dataService: DataService, private cdRef: ChangeDetectorRef) {} ngOnInit()

    { this.dataService.updates$.subscribe(newData => { this.data = newData; this.cdRef.markForCheck(); }); } Angular Performance So zünden Sie den Turbo Async Pipe
  52. Simplifying OnPush // component.ts data$: Observable<string>; constructor(dataService: DataService) { this.data$

    = this.dataService.updates$; } // component.html {{ data$ | async }} Angular Performance So zünden Sie den Turbo Async Pipe
  53. ng g c async Use <app-async></app-async> in AppComponent Make AsyncComponent

    OnPush // async.component.ts title$ = of('foo').pipe(delay(1000)); // async.component.html {{ title$ | async }} Angular Performance So zünden Sie den Turbo Async Pipe EX #5
  54. - Reduce initial load (size & computation) - Reduce perceived

    loading time - Prevent downloading the same resource again Angular Performance So zünden Sie den Turbo Load Time Performance
  55. Runtime Performance Bundling Lazy Loading Preloading Strategies Server-Side Rendering Service

    Worker Angular Performance So zünden Sie den Turbo Agenda Change Detection Basics Zone.js & NgZone Change Detection Strategies Change Detector Async Pipe Load Time Performance
  56. The Problem Angular’s development directory structure is hard to •

    deploy • serve • cache • … Lots of files, lots of requests Angular and its dependencies are large in size, apps use only a fragment Bundling So zünden Sie den Turbo Angular Performance
  57. The Problem Just-in-Time compilation (JiT) - Slow, client-side rendering -

    Compiler is 1.2 MB large in size - Template errors detected at runtime only - Potentially dangerous (injection attacks) Bundling So zünden Sie den Turbo Angular Performance
  58. The Problem Goal: Angular app - with all components pre-compiled

    - combined in a single (or few) file(s) - without redundant/unused code - uglified, compressed Bundling So zünden Sie den Turbo Angular Performance
  59. Angular Compilation Bundling Component @Component({ … }) class UserComponent {

    user = { name: 'Chris' }; } Template <div>hello {{ user.name }}</div> View Class var v = this.comp.user.name; So zünden Sie den Turbo Angular Performance
  60. JiT Compilation Bundling Component @Component({ … }) class UserComponent {

    user = { name: 'Chris' }; } Template <div>hello {{ user.name }}</div> Server Client Component @Component({ … }) class UserComponent { user = { name: 'Chris' }; } Template <div>hello {{ user.name }}</div> View Class var v = this.comp.user.name; So zünden Sie den Turbo Angular Performance
  61. AoT Compilation Bundling Component @Component({ … }) class UserComponent {

    user = { name: 'Chris' }; } Template <div>hello {{ user.name }}</div> Server Client Component @Component({ … }) class UserComponent { user = { name: 'Chris' }; } View Class var v = this.comp.user.name; Template <div>hello {{ user.name }}</div> View Class var v = this.comp.user.name; So zünden Sie den Turbo Angular Performance
  62. Tree Shaking “A Tree Shaker walks the dependency graph, top

    to bottom, and shakes out unused code like dead needles in a Christmas tree.” Bundling So zünden Sie den Turbo Angular Performance
  63. !function(){ var obj = { foo: function () { //

    Hi there! }, bar: function () { this.baz(); }, baz: function () { // stub } }; obj.foo(); }(); Tree Shaking Principle Bundling So zünden Sie den Turbo Angular Performance
  64. Build-Optimizer Contains Angular optimizations applicable to JavaScript code Folding static

    properties inside the class, scrubbing decorators, … Transformations help build tools to improve tree shaking Only in combination with AoT Enabled by default for AoT/production builds starting from Angular 5 Bundling So zünden Sie den Turbo Angular Performance
  65. Try some builds… ng build //no TS, JiT, no BO

    ng build --aot //no TS, AoT, no BO ng build --prod --build-optimizer=false // TS, AoT, no BO ng build --prod // TS, AoT, BO Bundling So zünden Sie den Turbo Angular Performance EX #6
  66. A Simple Demo App Dev build: 4.2 MB (without source

    maps) AoT build: 2.8 MB (without source maps) AoT+TreeShake: 502K AoT+TreeShake+BuildOptimizer: 379K (106K gzipped) Bundling So zünden Sie den Turbo Angular Performance
  67. A Simple Demo App JiT build: ~5500 ms AoT build:

    ~4900 ms Optimized build: ~9400ms 2018 MacBook Pro, served locally a few test runs, results may & will vary Bundling So zünden Sie den Turbo Angular Performance
  68. AoT Drawbacks Dynamic template compilation via ComponentFactoryResolver is discouraged in

    combination with AoT COMPILER_PROVIDERS are unavailable - https://github.com/angular/angular/issues/11780 Bundling So zünden Sie den Turbo Angular Performance
  69. Differential Loading Detect the platform and only deliver files required

    for this platform First version introduced with Angular CLI 7.3.0 core.js Polyfills required for ES5 browsers are only delivered to ES5 browsers Saves another 56+ K for modern browsers Angular Performance So zünden Sie den Turbo Bundling
  70. Differential Loading // angular.json "architect": { "build": { "builder": "@angular-devkit/build-angular:browser",

    "options": { "es5BrowserSupport": true } Angular Performance So zünden Sie den Turbo Bundling
  71. Differential Loading // index.html <!doctype html> <html lang="en"> <script type="text/javascript"

    src="runtime.js"></script> <script type="text/javascript" src="es2015-polyfills.js" nomodule></script> <script type="text/javascript" src="polyfills.js"></script> <script type="text/javascript" src="styles.js"></script> <script type="text/javascript" src="vendor.js"></script> <script type="text/javascript" src="main.js"></script></body> </html> Angular Performance So zünden Sie den Turbo Bundling
  72. Differential Loading Preview: - Differential loading support to come also

    for other files - Angular CLI will produce ES5 + ES2015 files of your application - ES2015 files (smaller footprint) will be delivered to modern browsers Angular Performance So zünden Sie den Turbo Bundling
  73. Runtime Performance Bundling Lazy Loading Preloading Strategies Server-Side Rendering Service

    Worker Angular Performance So zünden Sie den Turbo Agenda Change Detection Basics Zone.js & NgZone Change Detection Strategies Change Detector Async Pipe Load Time Performance
  74. Overview Angular router supports lazy loading components transparently Lazy loaded

    components are not delivered to/loaded by the client on boot, but on purpose Reduces load & perceived loading time Lazy Loading So zünden Sie den Turbo Angular Performance
  75. Architecture Lazy Loading is module-based Module is resolved by a

    module reference (e.g. SystemJS “URL”) Routing is delegated to the module called Lazy Loading So zünden Sie den Turbo Angular Performance
  76. ng g m lazy --routing ng g c lazy/lazy Add

    a route for LazyComponent to lazy/lazy-routing.module.ts const routes: Routes = [{ path: '', component: LazyComponent }]; Configure app-routing.module.ts as follows: const routes: Routes = [{ path: 'lazy', loadChildren: './lazy/lazy.module#LazyModule' }]; Angular Performance So zünden Sie den Turbo Lazy Loading EX #7
  77. Runtime Performance Bundling Lazy Loading Preloading Strategies Server-Side Rendering Service

    Worker Angular Performance So zünden Sie den Turbo Agenda Change Detection Basics Zone.js & NgZone Change Detection Strategies Change Detector Async Pipe Load Time Performance
  78. Configuring Lazy Loading NoPreloading - does not preload any route

    by default - advantage: low size footprint - disadvantage: takes some time after clicking a link to the lazy-loaded module, not offline capable PreloadAllModules - automatically preloads all modules after the application has launched (still better loading time!) - advantage: lazy-loaded modules now load instant (also on the first click), offline capable - disadvantage: higher footprint Angular Performance So zünden Sie den Turbo Preloading Strategies
  79. Configuring Lazy Loading @NgModule({ imports: [RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules, })],

    exports: [RouterModule] }) export class AppRoutingModule { } Angular Performance So zünden Sie den Turbo Preloading Strategies
  80. Custom Strategy It’s also possible to provide a custom strategy

    - when modules belong to each other - it’s expected that the user will access a certain module next (e.g. checkout after cart module) Developer can decide which modules should be preloaded on a navigation event Developer gets access to the modules which have not been preloaded yet Angular Performance So zünden Sie den Turbo Preloading Strategies
  81. Custom Strategy preload(route: Route, fn: () => Observable<any>): Observable<any> {

    // decide based on route (or other external information) // call fn to preload the module // otherwise, return of(null) } https://github.com/angular/angular/blob/7.2.10/packages/router/src/router_preloader.ts#L29-L58 Angular Performance So zünden Sie den Turbo Preloading Strategies
  82. Custom Strategy ng g s myPreloadingStrategy (automatically adds @Injectable which

    is great for this demo, but typically you would not call it a service) // myPreloadingStrategy.service.ts export class MyPreloadingStrategyService implements PreloadingStrategy preload(route: Route, fn: () => Observable<any>): Observable<any> { console.log(route); return fn(); } // app-routing.module.ts RouterModule.forRoot(routes, { preloadingStrategy: MyPreloadingStrategyService }) Angular Performance So zünden Sie den Turbo Preloading Strategies EX #8
  83. Runtime Performance Bundling Lazy Loading Preloading Strategies Server-Side Rendering Service

    Worker Angular Performance So zünden Sie den Turbo Agenda Change Detection Basics Zone.js & NgZone Change Detection Strategies Change Detector Async Pipe Load Time Performance
  84. Angular Universal Renders Angular content on a server (i.e. not

    in a browser environment) Provided by the Angular team Open Source https://github.com/angular/universal Has CLI integration Server-Side Rendering So zünden Sie den Turbo Angular Performance
  85. Angular App Application Layer Rendering Layer Web Worker Server Browser

    NativeScript … Platform Server-Side Rendering So zünden Sie den Turbo Angular Performance
  86. Principle Pre-render the website using the same sources that are

    served Once Angular kicks in, the view is replaced with the client-rendered one Supports Node.js (Express) & ASP.NET Core JiT and AoT support (AoT strictly recommended for production) Server-Side Rendering So zünden Sie den Turbo Angular Performance
  87. Principle Server-Side Rendering Component @Component({ … }) class UserComponent {

    user = { name: 'Chris' }; } Template <div>hello {{ user.name }}</div> Server Client Component @Component({ … }) class UserComponent { user = { name: 'Chris' }; } View Class var v = this.comp.user.name; Template <div>hello {{ user.name }}</div> View Class var v = this.comp.user.name; index.html <!DOCTYPE html><head>… So zünden Sie den Turbo Angular Performance
  88. Purpose Search Engine Optimization Preview Links (Social Media) Graceful Degradation

    Reduce Perceived Loading Time/Quick First Contentful Paint (FCP) Improve Performance for Mobile/Low-Powered Devices Server-Side Rendering So zünden Sie den Turbo Angular Performance
  89. Server Rendering Asset Downloads Client Init Client Data Paint The

    Web App Gap Server-Side Rendering So zünden Sie den Turbo Angular Performance
  90. Preboot.js Filling the Web App Gap Records interactions of the

    user on the server-rendered part Replays the interaction once Angular kicks in on the client side Provided by the Angular team Open source https://github.com/angular/preboot Server-Side Rendering So zünden Sie den Turbo Angular Performance
  91. Server Rendering Asset Downloads Client Init Client Data Paint Preboot.js

    & The Web App Gap Angular Performance So zünden Sie den Turbo Server-Side Rendering Record Replay
  92. Preboot.js & Angular @NgModule({ declarations: [AppComponent], imports: [ BrowserModule.withServerTransition({ appId:

    'foo' }), PrebootModule.withConfig({ appRoot: 'app-root' }) ], bootstrap: [AppComponent] }) export class AppModule { } Angular Performance So zünden Sie den Turbo Server-Side Rendering
  93. ng add @nguniversal/express-engine --clientProject perf-demo npm run build:ssr npm run

    serve:ssr http://localhost:4000 Check Network tab in DevTools Angular Performance So zünden Sie den Turbo Server-Side Rendering EX #9
  94. Runtime Performance Bundling Lazy Loading Preloading Strategies Server-Side Rendering Service

    Worker Angular Performance So zünden Sie den Turbo Agenda Change Detection Basics Zone.js & NgZone Change Detection Strategies Change Detector Async Pipe Load Time Performance
  95. Idea: Never load the same resource twice Download resources once

    and store them in a local cache The next time the user wants to open the application, load the contents from there Makes your application sources offline-capable Significantly improves loading time Angular Performance So zünden Sie den Turbo Service Worker
  96. Key Technology Service Worker Service Worker Internet Website HTML/JS Cache

    fetch So zünden Sie den Turbo Angular Performance
  97. @angular/service-worker Service Worker implementation provided by the Angular team Features

    - Caching - Offline Availability - Push Notifications Service Worker is generated by the CLI (prod builds only) Service Worker So zünden Sie den Turbo Angular Performance
  98. Features ng add @angular/pwa ng build --prod cd dist/browser npx

    lite-server Service Worker So zünden Sie den Turbo Angular Performance EX #10
  99. Workshop Angular & PWA: 21.03.2019 - 9:00–17:00 - Galilei 1+2

    Angular Performance So zünden Sie den Turbo Service Worker
  100. Runtime Performance Don’t over-optimize Reduce duration of a change detection

    cycle - Reduce amount of bindings - Avoid binding to (computationally intensive) getters or functions Reduce amount of change detection cycles - Disable zone - NgZone - Zone.js patches - ChangeDetectorRef - ChangeDetectionStrategy Angular Performance So zünden Sie den Turbo Summary