Angular Performance: Workshop
Improving Data Binding Performance with OnPush
-
Open the file
flight-search.component.tsand discover theFlightSearchComponent. Have a look to the methoddelaywhich is bound to the button with the labelDelay 1st Flight. -
Open the file
flight-card.component.tsand add have a look to theblinkmethod. -
Move to the file
flight-card.component.htmland create a data binding for this method at the end:{{ blink() }}Please note that binding methods is not a good idea with respect to performance. We do it here just to visualize the change tracker.
-
Open the solution in the browser and search for flights form
HamburgtoGraz. -
Click the button
Delay 1st Flightand see that just the first flight gets a new date. But you also see that every component is checked for changes by Angular b/c every component blinks. -
Open the file
flight-card.component.ts. Switch onOnPushfor yourFlightCard.Show Code
import {ChangeDetectionStrategy} from '@angular/core'; [...] @Component({ selector: 'flight-card', templateUrl: 'flight-card.component.html', changeDetection: ChangeDetectionStrategy.OnPush }) export class FlightCardComponent { [...] } -
If, and only if, you are not using
@ngrx/store: Open theflight.service.tsand alter it to update the selected flight's date in an immutable way:Show Code
// libs/flight-lib/src/services/flight.service.ts delay() { const ONE_MINUTE = 1000 * 60; let oldFlights = this.flights; let oldFlight = oldFlights[0]; let oldDate = new Date(oldFlight.date); // Mutable // oldDate.setTime(oldDate.getTime() + 15 * ONE_MINUTE ); // oldFlight.date = oldDate.toISOString(); // Immutable let newDate = new Date(oldDate.getTime() + 15 * ONE_MINUTE); let newFlight: Flight = { ...oldFlight, date: newDate.toISOString() }; let newFlights = [ newFlight, ...oldFlights.slice(1) ] this.flights = newFlights; }
You find some information about the object spread operator (e. g. ...oldFlight) here (scroll down to Object Spread) and about the array spread operator (e. g. [newFlight, ...oldFlights.slice(1)]) here.
- Make sure your implementation works. Switch to the browser and search for flights again. Click
Delay 1st Flightone more time and find out that Angular is just checking and updating the first flight card.
Improving Startup Performance with Prod-Mode
-
Make sure, your solution runs in debug mode (
ng serve -o) -
Open the performance tab in Chrome's dev tools and reload the app. Find out how long bootstrapping takes and create a screenshot.
Hint: In order to respect the cache, do it twice and take the screenshot after the 2nd try.
-
Install the simple web server serve:
npm install serve -g -
Switch to the console and move to the root folder of your project. Create a production build:
ng build --prod -
Start live-server for your production build. For this, switch to your project within the
dist(dist/apps/flight-app) folder and call serve:serve -s -
Open the performance tab in Chrome's dev tools and reload the app. Find out how long bootstrapping takes and create a screenshot.
Hint: In order to respect the cache, do it twice and take the screenshot after the 2nd try.
-
Compare your screenshot with the performance results.
Bonus: Inspecting Bundles with webpack-bundle-analyzer
Using the webpack-bundle-analyzer one can have a look at a bundle's content. In this exercise you will use this possibility by inspecting your AOT-based and your AOT-less production build.
-
Install the
webpack-bundle-analyzerglobally (for the sake of simplicity):npm install -g webpack npm install -g webpack-bundle-analyzer -
Move to the root folder of your project. Create a Production Build without AOT and generate a statistics file for the analyzer using the
stats-jsonflag:ng build --prod --aot=false --build-optimizer=false --stats-json -
Analyze your bundles:
cd dist/apps/flight-app webpack-bundle-analyzer stats.jsonThe name of
stats.jsoncan be slightly different on your machine, e. g.stats-es5.jsonorstats-es2015.json. -
Take a screen shot to document this.
-
Move to the root folder of your project. Create a production build using AOT:
ng build --prod --stats-json -
Analyze these bundles too and compare it to the former bundles:
cd dist/apps/flight-app webpack-bundle-analyzer stats.json
Bonus: Implementing a Custom Preloading Strategy **
-
Here you find some information about creating a custom preloading strategy. Have a look at it.
-
Create a custom preloading strategy that only preloads modules that have been marked with the
dataattribute in the router configuration. -
Configure the system to make use of it and test it.