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

Christian Liebel

September 03, 2020
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 - 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
  2. 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
  3. 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
  4. Requirements for hands-on labs: Node.js + Angular CLI + Google

    Chrome + Editor Repo: https://liebel.io/ngp20m 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 --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
  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": "~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
  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! DEMO
  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__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!
  33. 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
  34. 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!
  35. 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
  36. 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
  37. 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
  38. 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
  39. // 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
  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. 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
  42. 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
  43. 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
  44. 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
  45. 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!
  46. 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
  47. 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
  48. 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
  49. 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
  50. 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
  51. 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
  52. 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
  53. 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
  54. 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
  55. - 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
  56. 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
  57. 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
  58. 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
  59. 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
  60. 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
  61. 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
  62. 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
  63. 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
  64. !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
  65. 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
  66. 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
  67. 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
  68. 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
  69. 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
  70. 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
  71. 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
  72. 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
  73. 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
  74. 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
  75. 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
  76. 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
  77. 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
  78. 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
  79. 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
  80. 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
  81. 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
  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. 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
  84. 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
  85. 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
  86. 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
  87. Key Technology Service Worker Service Worker Internet Website HTML/JS Cache

    fetch So zünden Sie den Turbo Angular Performance
  88. 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
  89. 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