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 superschnell 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.

12c88a3a10478fa18d0363b3ba3d9df1?s=128

Christian Liebel

October 07, 2020
Tweet

Transcript

  1. Angular Performance So zünden Sie den Turbo Christian Liebel @christianliebel

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

    HTTP/2, compression, JS tweaks, CSS) - Deep-dive into performance metrics - 1:1 support 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
  3. Hello, it’s me. Angular Performance So zünden Sie den Turbo

    Christian Liebel Twitter: @christianliebel Email: christian.liebel @thinktecture.com Angular & PWA Slides: thinktecture.com /christian-liebel
  4. Angular Performance So zünden Sie den Turbo Timetable 09:00–10:30 Part

    I 10:30–11:00 Coffee break 11:00–12:30 Part II
  5. Requirements for hands-on labs: Node.js + Angular CLI + Google

    Chrome + Editor Angular Performance So zünden Sie den Turbo
  6. 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
  7. 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
  8. Don’t over-optimize. Angular Performance So zünden Sie den Turbo First

    Rule
  9. Reduce required computations during runtime - calculations - painting -

    layouting - … Today: Angular-specific performance topics Angular Performance So zünden Sie den Turbo Runtime Performance
  10. 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
  11. 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
  12. 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
  13. 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
  14. Component Tree AppComponent NavComponent ContentComponent ListComponent Angular Performance So zünden

    Sie den Turbo Change Detection
  15. 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
  16. 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>
  17. 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
  18. 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
  19. 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
  20. Command Line: ng new perf-demo --routing --style=css // 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
  21. 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
  22. 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
  23. A look at Angular’s dependencies "dependencies": { "@angular/common": "~10.0.14", "rxjs":

    "~6.5.5", "tslib": "^2.0.0", "zone.js": "~0.10.3" }, Zone.js So zünden Sie den Turbo Angular Performance
  24. 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
  25. 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
  26. 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
  27. 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
  28. A Meta-Monkey Patch Zone.js setTimeout setInterval geolocation.getCurrentPosition XMLHttpRequest PromiseRejectionEvent requestAnimationFrame

    click focus mousemove addEventListener So zünden Sie den Turbo Angular Performance
  29. NgZone Angular Performance So zünden Sie den Turbo Zone.js current

    (global) zone NgZone Angular boot
  30. 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
  31. 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()
  32. 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
  33. 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
  34. 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! DEMO
  35. 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
  36. NgZone Zone.js current (global) zone NgZone rAF rAF rAF rAF

    So zünden Sie den Turbo Angular Performance
  37. 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__UNPATCHED_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!
  38. Event Coalescing <div (click)="doSomething()"> <button (click)="doSomethingElse()">Test</button> </div> // main.ts platformBrowserDynamic().bootstrapModule(AppModule,

    { ngZoneEventCoalescing: true }); Angular Performance So zünden Sie den Turbo Zone.js ! App behavior may change! CHANGE CHANGE Coalescing
  39. 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!
  40. 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
  41. 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
  42. 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
  43. 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
  44. // 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
  45. 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
  46. 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
  47. 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
  48. 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
  49. 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
  50. 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!
  51. 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
  52. 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
  53. Findings Reduce amount of change detection cycles - Disable Zone.js

    (not a good idea in most cases) - Coalesce CD cycles (might change behavior of existing apps) - 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
  54. 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
  55. 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
  56. 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
  57. 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
  58. 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
  59. 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
  60. - 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
  61. 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
  62. 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
  63. 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
  64. 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
  65. 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
  66. <h1>{{ title }}</h1> Bundling So zünden Sie den Turbo Angular

    Performance
  67. 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
  68. 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
  69. 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
  70. !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
  71. Differential Loading ES5: function add(a,b){return a+b} ES 2015: add=(a,b)=>a+b ES

    2015 introduced shorter syntax (smaller footprint/saves bandwidth) Detect the platform and only deliver files required for this platform Larger ES5 bundles are only delivered to legacy browsers Note: ES5 bundles are disabled unless targeting older browsers Angular Performance So zünden Sie den Turbo Bundling
  72. Differential Loading // index.html <!doctype html> <html lang="en"><body> <script src="runtime-es2015.b948044840398824f16e.js"

    type="module"></script> <script src="runtime-es5.b948044840398824f16e.js" nomodule defer> </body></html> Angular Performance So zünden Sie den Turbo Bundling
  73. Try some builds… ng build --aot false //no Tree Shaking,

    JiT ng build //no Tree Shaking, AoT ng build --prod // Tree Shaking, AoT Do not count Source Maps (*.js.map) and ES5 bundles (if any). Bundling So zünden Sie den Turbo Angular Performance EX #6
  74. A Simple Demo App Dev build: 4.1 MB (ES 2015,

    without source maps) AoT build: 2.6 MB (ES 2015, without source maps) AoT+Tree Shaking: 274K (ES 2015, 83K gzipped) Bundling So zünden Sie den Turbo Angular Performance
  75. A Simple Demo App JiT build: ~24018 ms AoT build:

    ~15530 ms AoT+Tree Shaking: ~20731 ms 2018 MacBook Pro, served locally a few test runs, results may & will vary Bundling So zünden Sie den Turbo Angular Performance
  76. AoT Drawbacks Dynamic template compilation is discouraged in combination with

    AoT JitCompiler is unavailable - https://github.com/angular/angular/issues/15510 Bundling So zünden Sie den Turbo Angular Performance
  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. 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
  79. Architecture Lazy Loading is module-based Module is resolved via a

    dynamic import: import('./feature.module').then(m => m.FeatureModule) Routing is delegated to the feature module called Lazy Loading So zünden Sie den Turbo Angular Performance
  80. Overview const ROUTES: Routes = [{ path: 'admin', loadChildren: ()

    => import('app/admin/admin.module') .then(a => a.AdminModule) }]; Lazy Loading So zünden Sie den Turbo Angular Performance
  81. 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: () => import('./lazy/lazy.module').then(l => l.LazyModule) }]; Angular Performance So zünden Sie den Turbo Lazy Loading EX #7
  82. 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
  83. 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
  84. 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
  85. 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
  86. 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/8.2.10/packages/router/src/router_preloader.ts#L30-L58 Angular Performance So zünden Sie den Turbo Preloading Strategies
  87. 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
  88. 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
  89. 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
  90. Angular App Application Layer Rendering Layer Web Worker Server Browser

    NativeScript … Platform Server-Side Rendering So zünden Sie den Turbo Angular Performance
  91. 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, Hapi.js & plain sockets JiT and AoT support (AoT strictly recommended for production) Server-Side Rendering So zünden Sie den Turbo Angular Performance
  92. 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
  93. 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
  94. Server Rendering Asset Downloads Client Init Client Data Paint The

    Web App Gap Server-Side Rendering So zünden Sie den Turbo Angular Performance
  95. Preboot 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
  96. Server Rendering Asset Downloads Client Init Client Data Paint Preboot

    & The Web App Gap Angular Performance So zünden Sie den Turbo Server-Side Rendering Record Replay
  97. Preboot & 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
  98. 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
  99. 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
  100. 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
  101. Key Technology Service Worker Service Worker Internet Website HTML/JS Cache

    fetch So zünden Sie den Turbo Angular Performance
  102. @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
  103. 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
  104. 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 or coalesce events - NgZone - Zone.js patches - ChangeDetectorRef - ChangeDetectionStrategy Angular Performance So zünden Sie den Turbo Summary
  105. Thank you for your kind attention! Christian Liebel @christianliebel christian.liebel@thinktecture.com